1 //===--- RewriteBlocks.cpp ----------------------------------------------===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // Hacks and fun related to the closure rewriter.
12 //===----------------------------------------------------------------------===//
14 #include "ASTConsumers.h"
15 #include "clang/Rewrite/Rewriter.h"
16 #include "clang/AST/AST.h"
17 #include "clang/AST/ASTConsumer.h"
18 #include "clang/Basic/SourceManager.h"
19 #include "clang/Basic/IdentifierTable.h"
20 #include "clang/Basic/Diagnostic.h"
21 #include "clang/Basic/LangOptions.h"
22 #include "llvm/Support/MemoryBuffer.h"
23 #include "llvm/ADT/StringExtras.h"
24 #include "llvm/ADT/SmallPtrSet.h"
27 using namespace clang
;
32 class RewriteBlocks
: public ASTConsumer
{
35 const LangOptions
&LangOpts
;
36 unsigned RewriteFailedDiag
;
41 const char *MainFileStart
, *MainFileEnd
;
44 llvm::SmallVector
<BlockExpr
*, 32> Blocks
;
45 llvm::SmallVector
<BlockDeclRefExpr
*, 32> BlockDeclRefs
;
46 llvm::DenseMap
<BlockDeclRefExpr
*, CallExpr
*> BlockCallExprs
;
48 // Block related declarations.
49 llvm::SmallPtrSet
<ValueDecl
*, 8> BlockByCopyDecls
;
50 llvm::SmallPtrSet
<ValueDecl
*, 8> BlockByRefDecls
;
51 llvm::SmallPtrSet
<ValueDecl
*, 8> ImportedBlockDecls
;
53 llvm::DenseMap
<BlockExpr
*, std::string
> RewrittenBlockExprs
;
55 // The function/method we are rewriting.
56 FunctionDecl
*CurFunctionDef
;
57 ObjCMethodDecl
*CurMethodDef
;
60 std::string InFileName
;
61 std::string OutFileName
;
65 RewriteBlocks(std::string inFile
, std::string outFile
, Diagnostic
&D
,
66 const LangOptions
&LOpts
);
68 // Get the buffer corresponding to MainFileID.
69 // If we haven't changed it, then we are done.
70 if (const RewriteBuffer
*RewriteBuf
=
71 Rewrite
.getRewriteBufferFor(MainFileID
)) {
72 std::string
S(RewriteBuf
->begin(), RewriteBuf
->end());
73 printf("%s\n", S
.c_str());
75 printf("No changes\n");
79 void Initialize(ASTContext
&context
);
81 void InsertText(SourceLocation Loc
, const char *StrData
, unsigned StrLen
);
82 void ReplaceText(SourceLocation Start
, unsigned OrigLength
,
83 const char *NewStr
, unsigned NewLength
);
85 // Top Level Driver code.
86 virtual void HandleTopLevelDecl(Decl
*D
);
87 void HandleDeclInMainFile(Decl
*D
);
90 Stmt
*RewriteFunctionBody(Stmt
*S
);
91 void InsertBlockLiteralsWithinFunction(FunctionDecl
*FD
);
92 void InsertBlockLiteralsWithinMethod(ObjCMethodDecl
*MD
);
94 // Block specific rewrite rules.
95 std::string
SynthesizeBlockInitExpr(BlockExpr
*Exp
, VarDecl
*VD
=0);
97 void RewriteBlockCall(CallExpr
*Exp
);
98 void RewriteBlockPointerDecl(NamedDecl
*VD
);
99 void RewriteBlockDeclRefExpr(BlockDeclRefExpr
*VD
);
100 void RewriteBlockPointerFunctionArgs(FunctionDecl
*FD
);
102 std::string
SynthesizeBlockHelperFuncs(BlockExpr
*CE
, int i
,
103 const char *funcName
, std::string Tag
);
104 std::string
SynthesizeBlockFunc(BlockExpr
*CE
, int i
,
105 const char *funcName
, std::string Tag
);
106 std::string
SynthesizeBlockImpl(BlockExpr
*CE
, std::string Tag
,
107 bool hasCopyDisposeHelpers
);
108 std::string
SynthesizeBlockCall(CallExpr
*Exp
);
109 void SynthesizeBlockLiterals(SourceLocation FunLocStart
,
110 const char *FunName
);
112 void CollectBlockDeclRefInfo(BlockExpr
*Exp
);
113 void GetBlockCallExprs(Stmt
*S
);
114 void GetBlockDeclRefExprs(Stmt
*S
);
116 // We avoid calling Type::isBlockPointerType(), since it operates on the
117 // canonical type. We only care if the top-level type is a closure pointer.
118 bool isBlockPointerType(QualType T
) { return isa
<BlockPointerType
>(T
); }
120 // FIXME: This predicate seems like it would be useful to add to ASTContext.
121 bool isObjCType(QualType T
) {
122 if (!LangOpts
.ObjC1
&& !LangOpts
.ObjC2
)
125 QualType OCT
= Context
->getCanonicalType(T
).getUnqualifiedType();
127 if (OCT
== Context
->getCanonicalType(Context
->getObjCIdType()) ||
128 OCT
== Context
->getCanonicalType(Context
->getObjCClassType()))
131 if (const PointerType
*PT
= OCT
->getAsPointerType()) {
132 if (isa
<ObjCInterfaceType
>(PT
->getPointeeType()) ||
133 isa
<ObjCQualifiedIdType
>(PT
->getPointeeType()))
138 // ObjC rewrite methods.
139 void RewriteInterfaceDecl(ObjCInterfaceDecl
*ClassDecl
);
140 void RewriteCategoryDecl(ObjCCategoryDecl
*CatDecl
);
141 void RewriteProtocolDecl(ObjCProtocolDecl
*PDecl
);
142 void RewriteMethodDecl(ObjCMethodDecl
*MDecl
);
144 void RewriteFunctionTypeProto(QualType funcType
, NamedDecl
*D
);
145 void CheckFunctionPointerDecl(QualType dType
, NamedDecl
*ND
);
146 void RewriteCastExpr(CastExpr
*CE
);
148 bool PointerTypeTakesAnyBlockArguments(QualType QT
);
149 void GetExtentOfArgList(const char *Name
, const char *&LParen
, const char *&RParen
);
154 static bool IsHeaderFile(const std::string
&Filename
) {
155 std::string::size_type DotPos
= Filename
.rfind('.');
157 if (DotPos
== std::string::npos
) {
162 std::string Ext
= std::string(Filename
.begin()+DotPos
+1, Filename
.end());
164 // C++ header: .hh or .H;
165 return Ext
== "h" || Ext
== "hh" || Ext
== "H";
168 RewriteBlocks::RewriteBlocks(std::string inFile
, std::string outFile
,
169 Diagnostic
&D
, const LangOptions
&LOpts
) :
170 Diags(D
), LangOpts(LOpts
) {
171 IsHeader
= IsHeaderFile(inFile
);
173 OutFileName
= outFile
;
176 RewriteFailedDiag
= Diags
.getCustomDiagID(Diagnostic::Warning
,
180 ASTConsumer
*clang::CreateBlockRewriter(const std::string
& InFile
,
181 const std::string
& OutFile
,
183 const LangOptions
&LangOpts
) {
184 return new RewriteBlocks(InFile
, OutFile
, Diags
, LangOpts
);
187 void RewriteBlocks::Initialize(ASTContext
&context
) {
189 SM
= &Context
->getSourceManager();
191 // Get the ID and start/end of the main file.
192 MainFileID
= SM
->getMainFileID();
193 const llvm::MemoryBuffer
*MainBuf
= SM
->getBuffer(MainFileID
);
194 MainFileStart
= MainBuf
->getBufferStart();
195 MainFileEnd
= MainBuf
->getBufferEnd();
197 Rewrite
.setSourceMgr(Context
->getSourceManager());
200 Preamble
= "#pragma once\n";
201 Preamble
+= "#ifndef BLOCK_IMPL\n";
202 Preamble
+= "#define BLOCK_IMPL\n";
203 Preamble
+= "struct __block_impl {\n";
204 Preamble
+= " void *isa;\n";
205 Preamble
+= " int Flags;\n";
206 Preamble
+= " int Size;\n";
207 Preamble
+= " void *FuncPtr;\n";
209 Preamble
+= "enum {\n";
210 Preamble
+= " BLOCK_HAS_COPY_DISPOSE = (1<<25),\n";
211 Preamble
+= " BLOCK_IS_GLOBAL = (1<<28)\n";
213 if (LangOpts
.Microsoft
)
214 Preamble
+= "#define __OBJC_RW_EXTERN extern \"C\" __declspec(dllimport)\n";
216 Preamble
+= "#define __OBJC_RW_EXTERN extern\n";
217 Preamble
+= "// Runtime copy/destroy helper functions\n";
218 Preamble
+= "__OBJC_RW_EXTERN void _Block_copy_assign(void *, void *);\n";
219 Preamble
+= "__OBJC_RW_EXTERN void _Block_byref_assign_copy(void *, void *);\n";
220 Preamble
+= "__OBJC_RW_EXTERN void _Block_destroy(void *);\n";
221 Preamble
+= "__OBJC_RW_EXTERN void _Block_byref_release(void *);\n";
222 Preamble
+= "__OBJC_RW_EXTERN void *_NSConcreteGlobalBlock;\n";
223 Preamble
+= "__OBJC_RW_EXTERN void *_NSConcreteStackBlock;\n";
224 Preamble
+= "#endif\n";
226 InsertText(SourceLocation::getFileLoc(MainFileID
, 0),
227 Preamble
.c_str(), Preamble
.size());
230 void RewriteBlocks::InsertText(SourceLocation Loc
, const char *StrData
,
233 if (!Rewrite
.InsertText(Loc
, StrData
, StrLen
))
235 Diags
.Report(Context
->getFullLoc(Loc
), RewriteFailedDiag
);
238 void RewriteBlocks::ReplaceText(SourceLocation Start
, unsigned OrigLength
,
239 const char *NewStr
, unsigned NewLength
) {
240 if (!Rewrite
.ReplaceText(Start
, OrigLength
, NewStr
, NewLength
))
242 Diags
.Report(Context
->getFullLoc(Start
), RewriteFailedDiag
);
245 void RewriteBlocks::RewriteMethodDecl(ObjCMethodDecl
*Method
) {
246 bool haveBlockPtrs
= false;
247 for (ObjCMethodDecl::param_iterator I
= Method
->param_begin(),
248 E
= Method
->param_end(); I
!= E
; ++I
)
249 if (isBlockPointerType((*I
)->getType()))
250 haveBlockPtrs
= true;
255 // Do a fuzzy rewrite.
256 // We have 1 or more arguments that have closure pointers.
257 SourceLocation Loc
= Method
->getLocStart();
258 SourceLocation LocEnd
= Method
->getLocEnd();
259 const char *startBuf
= SM
->getCharacterData(Loc
);
260 const char *endBuf
= SM
->getCharacterData(LocEnd
);
262 const char *methodPtr
= startBuf
;
263 std::string Tag
= "struct __block_impl *";
265 while (*methodPtr
++ && (methodPtr
!= endBuf
)) {
266 switch (*methodPtr
) {
269 if (*methodPtr
== '(') {
270 const char *scanType
= ++methodPtr
;
271 bool foundBlockPointer
= false;
272 unsigned parenCount
= 1;
283 foundBlockPointer
= true;
288 if (foundBlockPointer
) {
289 // advance the location to startArgList.
290 Loc
= Loc
.getFileLocWithOffset(methodPtr
-startBuf
);
291 assert((Loc
.isValid()) && "Invalid Loc");
292 ReplaceText(Loc
, scanType
-methodPtr
-1, Tag
.c_str(), Tag
.size());
294 // Advance startBuf. Since the underlying buffer has changed,
295 // it's very important to advance startBuf (so we can correctly
296 // compute a relative Loc the next time around).
297 startBuf
= methodPtr
;
299 // Advance the method ptr to the end of the type.
300 methodPtr
= scanType
;
308 void RewriteBlocks::RewriteInterfaceDecl(ObjCInterfaceDecl
*ClassDecl
) {
309 for (ObjCInterfaceDecl::instmeth_iterator I
= ClassDecl
->instmeth_begin(),
310 E
= ClassDecl
->instmeth_end(); I
!= E
; ++I
)
311 RewriteMethodDecl(*I
);
312 for (ObjCInterfaceDecl::classmeth_iterator I
= ClassDecl
->classmeth_begin(),
313 E
= ClassDecl
->classmeth_end(); I
!= E
; ++I
)
314 RewriteMethodDecl(*I
);
317 void RewriteBlocks::RewriteCategoryDecl(ObjCCategoryDecl
*CatDecl
) {
318 for (ObjCCategoryDecl::instmeth_iterator I
= CatDecl
->instmeth_begin(),
319 E
= CatDecl
->instmeth_end(); I
!= E
; ++I
)
320 RewriteMethodDecl(*I
);
321 for (ObjCCategoryDecl::classmeth_iterator I
= CatDecl
->classmeth_begin(),
322 E
= CatDecl
->classmeth_end(); I
!= E
; ++I
)
323 RewriteMethodDecl(*I
);
326 void RewriteBlocks::RewriteProtocolDecl(ObjCProtocolDecl
*PDecl
) {
327 for (ObjCProtocolDecl::instmeth_iterator I
= PDecl
->instmeth_begin(),
328 E
= PDecl
->instmeth_end(); I
!= E
; ++I
)
329 RewriteMethodDecl(*I
);
330 for (ObjCProtocolDecl::classmeth_iterator I
= PDecl
->classmeth_begin(),
331 E
= PDecl
->classmeth_end(); I
!= E
; ++I
)
332 RewriteMethodDecl(*I
);
335 //===----------------------------------------------------------------------===//
336 // Top Level Driver Code
337 //===----------------------------------------------------------------------===//
339 void RewriteBlocks::HandleTopLevelDecl(Decl
*D
) {
340 // Two cases: either the decl could be in the main file, or it could be in a
341 // #included file. If the former, rewrite it now. If the later, check to see
342 // if we rewrote the #include/#import.
343 SourceLocation Loc
= D
->getLocation();
344 Loc
= SM
->getLogicalLoc(Loc
);
346 // If this is for a builtin, ignore it.
347 if (Loc
.isInvalid()) return;
349 if (ObjCInterfaceDecl
*MD
= dyn_cast
<ObjCInterfaceDecl
>(D
))
350 RewriteInterfaceDecl(MD
);
351 else if (ObjCCategoryDecl
*CD
= dyn_cast
<ObjCCategoryDecl
>(D
))
352 RewriteCategoryDecl(CD
);
353 else if (ObjCProtocolDecl
*PD
= dyn_cast
<ObjCProtocolDecl
>(D
))
354 RewriteProtocolDecl(PD
);
356 // If we have a decl in the main file, see if we should rewrite it.
357 if (SM
->getDecomposedFileLoc(Loc
).first
== MainFileID
)
358 HandleDeclInMainFile(D
);
362 std::string
RewriteBlocks::SynthesizeBlockFunc(BlockExpr
*CE
, int i
,
363 const char *funcName
,
365 const FunctionType
*AFT
= CE
->getFunctionType();
366 QualType RT
= AFT
->getResultType();
367 std::string StructRef
= "struct " + Tag
;
368 std::string S
= "static " + RT
.getAsString() + " __" +
369 funcName
+ "_" + "block_func_" + utostr(i
);
371 BlockDecl
*BD
= CE
->getBlockDecl();
373 if (isa
<FunctionTypeNoProto
>(AFT
)) {
375 } else if (BD
->param_empty()) {
376 S
+= "(" + StructRef
+ " *__cself)";
378 const FunctionTypeProto
*FT
= cast
<FunctionTypeProto
>(AFT
);
379 assert(FT
&& "SynthesizeBlockFunc: No function proto");
381 // first add the implicit argument.
382 S
+= StructRef
+ " *__cself, ";
383 std::string ParamStr
;
384 for (BlockDecl::param_iterator AI
= BD
->param_begin(),
385 E
= BD
->param_end(); AI
!= E
; ++AI
) {
386 if (AI
!= BD
->param_begin()) S
+= ", ";
387 ParamStr
= (*AI
)->getName();
388 (*AI
)->getType().getAsStringInternal(ParamStr
);
391 if (FT
->isVariadic()) {
392 if (!BD
->param_empty()) S
+= ", ";
399 // Create local declarations to avoid rewriting all closure decl ref exprs.
400 // First, emit a declaration for all "by ref" decls.
401 for (llvm::SmallPtrSet
<ValueDecl
*,8>::iterator I
= BlockByRefDecls
.begin(),
402 E
= BlockByRefDecls
.end(); I
!= E
; ++I
) {
404 std::string Name
= (*I
)->getName();
405 Context
->getPointerType((*I
)->getType()).getAsStringInternal(Name
);
406 S
+= Name
+ " = __cself->" + (*I
)->getName() + "; // bound by ref\n";
408 // Next, emit a declaration for all "by copy" declarations.
409 for (llvm::SmallPtrSet
<ValueDecl
*,8>::iterator I
= BlockByCopyDecls
.begin(),
410 E
= BlockByCopyDecls
.end(); I
!= E
; ++I
) {
412 std::string Name
= (*I
)->getName();
413 // Handle nested closure invocation. For example:
415 // void (^myImportedClosure)(void);
416 // myImportedClosure = ^(void) { setGlobalInt(x + y); };
418 // void (^anotherClosure)(void);
419 // anotherClosure = ^(void) {
420 // myImportedClosure(); // import and invoke the closure
423 if (isBlockPointerType((*I
)->getType()))
424 S
+= "struct __block_impl *";
426 (*I
)->getType().getAsStringInternal(Name
);
427 S
+= Name
+ " = __cself->" + (*I
)->getName() + "; // bound by copy\n";
429 std::string RewrittenStr
= RewrittenBlockExprs
[CE
];
430 const char *cstr
= RewrittenStr
.c_str();
431 while (*cstr
++ != '{') ;
437 std::string
RewriteBlocks::SynthesizeBlockHelperFuncs(BlockExpr
*CE
, int i
,
438 const char *funcName
,
440 std::string StructRef
= "struct " + Tag
;
441 std::string S
= "static void __";
444 S
+= "_block_copy_" + utostr(i
);
445 S
+= "(" + StructRef
;
446 S
+= "*dst, " + StructRef
;
448 for (llvm::SmallPtrSet
<ValueDecl
*,8>::iterator I
= ImportedBlockDecls
.begin(),
449 E
= ImportedBlockDecls
.end(); I
!= E
; ++I
) {
450 S
+= "_Block_copy_assign(&dst->";
451 S
+= (*I
)->getName();
453 S
+= (*I
)->getName();
456 S
+= "\nstatic void __";
458 S
+= "_block_dispose_" + utostr(i
);
459 S
+= "(" + StructRef
;
461 for (llvm::SmallPtrSet
<ValueDecl
*,8>::iterator I
= ImportedBlockDecls
.begin(),
462 E
= ImportedBlockDecls
.end(); I
!= E
; ++I
) {
463 S
+= "_Block_destroy(src->";
464 S
+= (*I
)->getName();
471 std::string
RewriteBlocks::SynthesizeBlockImpl(BlockExpr
*CE
, std::string Tag
,
472 bool hasCopyDisposeHelpers
) {
473 std::string S
= "struct " + Tag
;
474 std::string Constructor
= " " + Tag
;
476 S
+= " {\n struct __block_impl impl;\n";
478 if (hasCopyDisposeHelpers
)
479 S
+= " void *copy;\n void *dispose;\n";
481 Constructor
+= "(void *fp";
483 if (hasCopyDisposeHelpers
)
484 Constructor
+= ", void *copyHelp, void *disposeHelp";
486 if (BlockDeclRefs
.size()) {
487 // Output all "by copy" declarations.
488 for (llvm::SmallPtrSet
<ValueDecl
*,8>::iterator I
= BlockByCopyDecls
.begin(),
489 E
= BlockByCopyDecls
.end(); I
!= E
; ++I
) {
491 std::string FieldName
= (*I
)->getName();
492 std::string ArgName
= "_" + FieldName
;
493 // Handle nested closure invocation. For example:
495 // void (^myImportedBlock)(void);
496 // myImportedBlock = ^(void) { setGlobalInt(x + y); };
498 // void (^anotherBlock)(void);
499 // anotherBlock = ^(void) {
500 // myImportedBlock(); // import and invoke the closure
503 if (isBlockPointerType((*I
)->getType())) {
504 S
+= "struct __block_impl *";
505 Constructor
+= ", void *" + ArgName
;
507 (*I
)->getType().getAsStringInternal(FieldName
);
508 (*I
)->getType().getAsStringInternal(ArgName
);
509 Constructor
+= ", " + ArgName
;
511 S
+= FieldName
+ ";\n";
513 // Output all "by ref" declarations.
514 for (llvm::SmallPtrSet
<ValueDecl
*,8>::iterator I
= BlockByRefDecls
.begin(),
515 E
= BlockByRefDecls
.end(); I
!= E
; ++I
) {
517 std::string FieldName
= (*I
)->getName();
518 std::string ArgName
= "_" + FieldName
;
519 // Handle nested closure invocation. For example:
521 // void (^myImportedBlock)(void);
522 // myImportedBlock = ^(void) { setGlobalInt(x + y); };
524 // void (^anotherBlock)(void);
525 // anotherBlock = ^(void) {
526 // myImportedBlock(); // import and invoke the closure
529 if (isBlockPointerType((*I
)->getType())) {
530 S
+= "struct __block_impl *";
531 Constructor
+= ", void *" + ArgName
;
533 Context
->getPointerType((*I
)->getType()).getAsStringInternal(FieldName
);
534 Context
->getPointerType((*I
)->getType()).getAsStringInternal(ArgName
);
535 Constructor
+= ", " + ArgName
;
537 S
+= FieldName
+ "; // by ref\n";
539 // Finish writing the constructor.
540 // FIXME: handle NSConcreteGlobalBlock.
541 Constructor
+= ", int flags=0) {\n";
542 Constructor
+= " impl.isa = 0/*&_NSConcreteStackBlock*/;\n impl.Size = sizeof(";
543 Constructor
+= Tag
+ ");\n impl.Flags = flags;\n impl.FuncPtr = fp;\n";
545 if (hasCopyDisposeHelpers
)
546 Constructor
+= " copy = copyHelp;\n dispose = disposeHelp;\n";
548 // Initialize all "by copy" arguments.
549 for (llvm::SmallPtrSet
<ValueDecl
*,8>::iterator I
= BlockByCopyDecls
.begin(),
550 E
= BlockByCopyDecls
.end(); I
!= E
; ++I
) {
551 std::string Name
= (*I
)->getName();
553 if (isBlockPointerType((*I
)->getType()))
554 Constructor
+= Name
+ " = (struct __block_impl *)_";
556 Constructor
+= Name
+ " = _";
557 Constructor
+= Name
+ ";\n";
559 // Initialize all "by ref" arguments.
560 for (llvm::SmallPtrSet
<ValueDecl
*,8>::iterator I
= BlockByRefDecls
.begin(),
561 E
= BlockByRefDecls
.end(); I
!= E
; ++I
) {
562 std::string Name
= (*I
)->getName();
564 if (isBlockPointerType((*I
)->getType()))
565 Constructor
+= Name
+ " = (struct __block_impl *)_";
567 Constructor
+= Name
+ " = _";
568 Constructor
+= Name
+ ";\n";
571 // Finish writing the constructor.
572 // FIXME: handle NSConcreteGlobalBlock.
573 Constructor
+= ", int flags=0) {\n";
574 Constructor
+= " impl.isa = 0/*&_NSConcreteStackBlock*/;\n impl.Size = sizeof(";
575 Constructor
+= Tag
+ ");\n impl.Flags = flags;\n impl.FuncPtr = fp;\n";
576 if (hasCopyDisposeHelpers
)
577 Constructor
+= " copy = copyHelp;\n dispose = disposeHelp;\n";
580 Constructor
+= "}\n";
586 void RewriteBlocks::SynthesizeBlockLiterals(SourceLocation FunLocStart
,
587 const char *FunName
) {
588 // Insert closures that were part of the function.
589 for (unsigned i
= 0; i
< Blocks
.size(); i
++) {
591 CollectBlockDeclRefInfo(Blocks
[i
]);
593 std::string Tag
= "__" + std::string(FunName
) + "_block_impl_" + utostr(i
);
595 std::string CI
= SynthesizeBlockImpl(Blocks
[i
], Tag
,
596 ImportedBlockDecls
.size() > 0);
598 InsertText(FunLocStart
, CI
.c_str(), CI
.size());
600 std::string CF
= SynthesizeBlockFunc(Blocks
[i
], i
, FunName
, Tag
);
602 InsertText(FunLocStart
, CF
.c_str(), CF
.size());
604 if (ImportedBlockDecls
.size()) {
605 std::string HF
= SynthesizeBlockHelperFuncs(Blocks
[i
], i
, FunName
, Tag
);
606 InsertText(FunLocStart
, HF
.c_str(), HF
.size());
609 BlockDeclRefs
.clear();
610 BlockByRefDecls
.clear();
611 BlockByCopyDecls
.clear();
612 BlockCallExprs
.clear();
613 ImportedBlockDecls
.clear();
616 RewrittenBlockExprs
.clear();
619 void RewriteBlocks::InsertBlockLiteralsWithinFunction(FunctionDecl
*FD
) {
620 SourceLocation FunLocStart
= FD
->getTypeSpecStartLoc();
621 const char *FuncName
= FD
->getName();
623 SynthesizeBlockLiterals(FunLocStart
, FuncName
);
626 void RewriteBlocks::InsertBlockLiteralsWithinMethod(ObjCMethodDecl
*MD
) {
627 SourceLocation FunLocStart
= MD
->getLocStart();
628 std::string FuncName
= std::string(MD
->getSelector().getName());
629 // Convert colons to underscores.
630 std::string::size_type loc
= 0;
631 while ((loc
= FuncName
.find(":", loc
)) != std::string::npos
)
632 FuncName
.replace(loc
, 1, "_");
634 SynthesizeBlockLiterals(FunLocStart
, FuncName
.c_str());
637 void RewriteBlocks::GetBlockDeclRefExprs(Stmt
*S
) {
638 for (Stmt::child_iterator CI
= S
->child_begin(), E
= S
->child_end();
641 if (BlockExpr
*CBE
= dyn_cast
<BlockExpr
>(*CI
))
642 GetBlockDeclRefExprs(CBE
->getBody());
644 GetBlockDeclRefExprs(*CI
);
646 // Handle specific things.
647 if (BlockDeclRefExpr
*CDRE
= dyn_cast
<BlockDeclRefExpr
>(S
))
648 // FIXME: Handle enums.
649 if (!isa
<FunctionDecl
>(CDRE
->getDecl()))
650 BlockDeclRefs
.push_back(CDRE
);
654 void RewriteBlocks::GetBlockCallExprs(Stmt
*S
) {
655 for (Stmt::child_iterator CI
= S
->child_begin(), E
= S
->child_end();
658 if (BlockExpr
*CBE
= dyn_cast
<BlockExpr
>(*CI
))
659 GetBlockCallExprs(CBE
->getBody());
661 GetBlockCallExprs(*CI
);
664 if (CallExpr
*CE
= dyn_cast
<CallExpr
>(S
)) {
665 if (CE
->getCallee()->getType()->isBlockPointerType()) {
666 BlockCallExprs
[dyn_cast
<BlockDeclRefExpr
>(CE
->getCallee())] = CE
;
672 std::string
RewriteBlocks::SynthesizeBlockCall(CallExpr
*Exp
) {
673 // Navigate to relevant type information.
674 const char *closureName
= 0;
675 const BlockPointerType
*CPT
= 0;
677 if (const DeclRefExpr
*DRE
= dyn_cast
<DeclRefExpr
>(Exp
->getCallee())) {
678 closureName
= DRE
->getDecl()->getName();
679 CPT
= DRE
->getType()->getAsBlockPointerType();
680 } else if (BlockDeclRefExpr
*CDRE
= dyn_cast
<BlockDeclRefExpr
>(Exp
->getCallee())) {
681 closureName
= CDRE
->getDecl()->getName();
682 CPT
= CDRE
->getType()->getAsBlockPointerType();
683 } else if (MemberExpr
*MExpr
= dyn_cast
<MemberExpr
>(Exp
->getCallee())) {
684 closureName
= MExpr
->getMemberDecl()->getName();
685 CPT
= MExpr
->getType()->getAsBlockPointerType();
687 assert(1 && "RewriteBlockClass: Bad type");
689 assert(CPT
&& "RewriteBlockClass: Bad type");
690 const FunctionType
*FT
= CPT
->getPointeeType()->getAsFunctionType();
691 assert(FT
&& "RewriteBlockClass: Bad type");
692 const FunctionTypeProto
*FTP
= dyn_cast
<FunctionTypeProto
>(FT
);
693 // FTP will be null for closures that don't take arguments.
695 // Build a closure call - start with a paren expr to enforce precedence.
696 std::string BlockCall
= "(";
698 // Synthesize the cast.
699 BlockCall
+= "(" + Exp
->getType().getAsString() + "(*)";
700 BlockCall
+= "(struct __block_impl *";
702 for (FunctionTypeProto::arg_type_iterator I
= FTP
->arg_type_begin(),
703 E
= FTP
->arg_type_end(); I
&& (I
!= E
); ++I
)
704 BlockCall
+= ", " + (*I
).getAsString();
706 BlockCall
+= "))"; // close the argument list and paren expression.
708 // Invoke the closure. We need to cast it since the declaration type is
709 // bogus (it's a function pointer type)
710 BlockCall
+= "((struct __block_impl *)";
711 std::string closureExprBufStr
;
712 llvm::raw_string_ostream
closureExprBuf(closureExprBufStr
);
713 Exp
->getCallee()->printPretty(closureExprBuf
);
714 BlockCall
+= closureExprBuf
.str();
715 BlockCall
+= ")->FuncPtr)";
717 // Add the arguments.
718 BlockCall
+= "((struct __block_impl *)";
719 BlockCall
+= closureExprBuf
.str();
720 for (CallExpr::arg_iterator I
= Exp
->arg_begin(),
721 E
= Exp
->arg_end(); I
!= E
; ++I
) {
722 std::string syncExprBufS
;
723 llvm::raw_string_ostream
Buf(syncExprBufS
);
724 (*I
)->printPretty(Buf
);
725 BlockCall
+= ", " + Buf
.str();
730 void RewriteBlocks::RewriteBlockCall(CallExpr
*Exp
) {
731 std::string BlockCall
= SynthesizeBlockCall(Exp
);
733 const char *startBuf
= SM
->getCharacterData(Exp
->getLocStart());
734 const char *endBuf
= SM
->getCharacterData(Exp
->getLocEnd());
736 ReplaceText(Exp
->getLocStart(), endBuf
-startBuf
,
737 BlockCall
.c_str(), BlockCall
.size());
740 void RewriteBlocks::RewriteBlockDeclRefExpr(BlockDeclRefExpr
*BDRE
) {
741 // FIXME: Add more elaborate code generation required by the ABI.
742 InsertText(BDRE
->getLocStart(), "*", 1);
745 void RewriteBlocks::RewriteCastExpr(CastExpr
*CE
) {
746 SourceLocation LocStart
= CE
->getLocStart();
747 SourceLocation LocEnd
= CE
->getLocEnd();
749 if (!Rewriter::isRewritable(LocStart
) || !Rewriter::isRewritable(LocEnd
))
752 const char *startBuf
= SM
->getCharacterData(LocStart
);
753 const char *endBuf
= SM
->getCharacterData(LocEnd
);
755 // advance the location to startArgList.
756 const char *argPtr
= startBuf
;
758 while (*argPtr
++ && (argPtr
< endBuf
)) {
761 // Replace the '^' with '*'.
762 LocStart
= LocStart
.getFileLocWithOffset(argPtr
-startBuf
);
763 ReplaceText(LocStart
, 1, "*", 1);
770 void RewriteBlocks::RewriteBlockPointerFunctionArgs(FunctionDecl
*FD
) {
771 SourceLocation DeclLoc
= FD
->getLocation();
772 unsigned parenCount
= 0;
774 // We have 1 or more arguments that have closure pointers.
775 const char *startBuf
= SM
->getCharacterData(DeclLoc
);
776 const char *startArgList
= strchr(startBuf
, '(');
778 assert((*startArgList
== '(') && "Rewriter fuzzy parser confused");
781 // advance the location to startArgList.
782 DeclLoc
= DeclLoc
.getFileLocWithOffset(startArgList
-startBuf
);
783 assert((DeclLoc
.isValid()) && "Invalid DeclLoc");
785 const char *argPtr
= startArgList
;
787 while (*argPtr
++ && parenCount
) {
790 // Replace the '^' with '*'.
791 DeclLoc
= DeclLoc
.getFileLocWithOffset(argPtr
-startArgList
);
792 ReplaceText(DeclLoc
, 1, "*", 1);
805 bool RewriteBlocks::PointerTypeTakesAnyBlockArguments(QualType QT
) {
806 const FunctionTypeProto
*FTP
;
807 const PointerType
*PT
= QT
->getAsPointerType();
809 FTP
= PT
->getPointeeType()->getAsFunctionTypeProto();
811 const BlockPointerType
*BPT
= QT
->getAsBlockPointerType();
812 assert(BPT
&& "BlockPointerTypeTakeAnyBlockArguments(): not a block pointer type");
813 FTP
= BPT
->getPointeeType()->getAsFunctionTypeProto();
816 for (FunctionTypeProto::arg_type_iterator I
= FTP
->arg_type_begin(),
817 E
= FTP
->arg_type_end(); I
!= E
; ++I
)
818 if (isBlockPointerType(*I
))
824 void RewriteBlocks::GetExtentOfArgList(const char *Name
,
825 const char *&LParen
, const char *&RParen
) {
826 const char *argPtr
= strchr(Name
, '(');
827 assert((*argPtr
== '(') && "Rewriter fuzzy parser confused");
829 LParen
= argPtr
; // output the start.
830 argPtr
++; // skip past the left paren.
831 unsigned parenCount
= 1;
833 while (*argPtr
&& parenCount
) {
835 case '(': parenCount
++; break;
836 case ')': parenCount
--; break;
839 if (parenCount
) argPtr
++;
841 assert((*argPtr
== ')') && "Rewriter fuzzy parser confused");
842 RParen
= argPtr
; // output the end
845 void RewriteBlocks::RewriteBlockPointerDecl(NamedDecl
*ND
) {
846 if (FunctionDecl
*FD
= dyn_cast
<FunctionDecl
>(ND
)) {
847 RewriteBlockPointerFunctionArgs(FD
);
850 // Handle Variables and Typedefs.
851 SourceLocation DeclLoc
= ND
->getLocation();
853 if (VarDecl
*VD
= dyn_cast
<VarDecl
>(ND
))
854 DeclT
= VD
->getType();
855 else if (TypedefDecl
*TDD
= dyn_cast
<TypedefDecl
>(ND
))
856 DeclT
= TDD
->getUnderlyingType();
857 else if (FieldDecl
*FD
= dyn_cast
<FieldDecl
>(ND
))
858 DeclT
= FD
->getType();
860 assert(0 && "RewriteBlockPointerDecl(): Decl type not yet handled");
862 const char *startBuf
= SM
->getCharacterData(DeclLoc
);
863 const char *endBuf
= startBuf
;
864 // scan backward (from the decl location) for the end of the previous decl.
865 while (*startBuf
!= '^' && *startBuf
!= ';' && startBuf
!= MainFileStart
)
868 // *startBuf != '^' if we are dealing with a pointer to function that
869 // may take block argument types (which will be handled below).
870 if (*startBuf
== '^') {
871 // Replace the '^' with '*', computing a negative offset.
872 DeclLoc
= DeclLoc
.getFileLocWithOffset(startBuf
-endBuf
);
873 ReplaceText(DeclLoc
, 1, "*", 1);
875 if (PointerTypeTakesAnyBlockArguments(DeclT
)) {
876 // Replace the '^' with '*' for arguments.
877 DeclLoc
= ND
->getLocation();
878 startBuf
= SM
->getCharacterData(DeclLoc
);
879 const char *argListBegin
, *argListEnd
;
880 GetExtentOfArgList(startBuf
, argListBegin
, argListEnd
);
881 while (argListBegin
< argListEnd
) {
882 if (*argListBegin
== '^') {
883 SourceLocation CaretLoc
= DeclLoc
.getFileLocWithOffset(argListBegin
-startBuf
);
884 ReplaceText(CaretLoc
, 1, "*", 1);
892 void RewriteBlocks::CollectBlockDeclRefInfo(BlockExpr
*Exp
) {
893 // Add initializers for any closure decl refs.
894 GetBlockDeclRefExprs(Exp
->getBody());
895 if (BlockDeclRefs
.size()) {
896 // Unique all "by copy" declarations.
897 for (unsigned i
= 0; i
< BlockDeclRefs
.size(); i
++)
898 if (!BlockDeclRefs
[i
]->isByRef())
899 BlockByCopyDecls
.insert(BlockDeclRefs
[i
]->getDecl());
900 // Unique all "by ref" declarations.
901 for (unsigned i
= 0; i
< BlockDeclRefs
.size(); i
++)
902 if (BlockDeclRefs
[i
]->isByRef()) {
903 BlockByRefDecls
.insert(BlockDeclRefs
[i
]->getDecl());
905 // Find any imported blocks...they will need special attention.
906 for (unsigned i
= 0; i
< BlockDeclRefs
.size(); i
++)
907 if (isBlockPointerType(BlockDeclRefs
[i
]->getType())) {
908 GetBlockCallExprs(Blocks
[i
]);
909 ImportedBlockDecls
.insert(BlockDeclRefs
[i
]->getDecl());
914 std::string
RewriteBlocks::SynthesizeBlockInitExpr(BlockExpr
*Exp
, VarDecl
*VD
) {
915 Blocks
.push_back(Exp
);
917 CollectBlockDeclRefInfo(Exp
);
918 std::string FuncName
;
921 FuncName
= std::string(CurFunctionDef
->getName());
922 else if (CurMethodDef
) {
923 FuncName
= std::string(CurMethodDef
->getSelector().getName());
924 // Convert colons to underscores.
925 std::string::size_type loc
= 0;
926 while ((loc
= FuncName
.find(":", loc
)) != std::string::npos
)
927 FuncName
.replace(loc
, 1, "_");
929 FuncName
= std::string(VD
->getName());
931 std::string BlockNumber
= utostr(Blocks
.size()-1);
933 std::string Tag
= "__" + FuncName
+ "_block_impl_" + BlockNumber
;
934 std::string Func
= "__" + FuncName
+ "_block_func_" + BlockNumber
;
936 std::string FunkTypeStr
;
938 // Get a pointer to the function type so we can cast appropriately.
939 Context
->getPointerType(QualType(Exp
->getFunctionType(),0)).getAsStringInternal(FunkTypeStr
);
941 // Rewrite the closure block with a compound literal. The first cast is
942 // to prevent warnings from the C compiler.
943 std::string Init
= "(" + FunkTypeStr
;
947 // Initialize the block function.
948 Init
+= "((void*)" + Func
;
950 if (ImportedBlockDecls
.size()) {
951 std::string Buf
= "__" + FuncName
+ "_block_copy_" + BlockNumber
;
952 Init
+= ",(void*)" + Buf
;
953 Buf
= "__" + FuncName
+ "_block_dispose_" + BlockNumber
;
954 Init
+= ",(void*)" + Buf
;
956 // Add initializers for any closure decl refs.
957 if (BlockDeclRefs
.size()) {
958 // Output all "by copy" declarations.
959 for (llvm::SmallPtrSet
<ValueDecl
*,8>::iterator I
= BlockByCopyDecls
.begin(),
960 E
= BlockByCopyDecls
.end(); I
!= E
; ++I
) {
962 if (isObjCType((*I
)->getType())) {
964 Init
+= (*I
)->getName();
965 Init
+= " retain] autorelease]";
966 } else if (isBlockPointerType((*I
)->getType())) {
968 Init
+= (*I
)->getName();
970 Init
+= (*I
)->getName();
973 // Output all "by ref" declarations.
974 for (llvm::SmallPtrSet
<ValueDecl
*,8>::iterator I
= BlockByRefDecls
.begin(),
975 E
= BlockByRefDecls
.end(); I
!= E
; ++I
) {
977 Init
+= (*I
)->getName();
981 BlockDeclRefs
.clear();
982 BlockByRefDecls
.clear();
983 BlockByCopyDecls
.clear();
984 ImportedBlockDecls
.clear();
989 //===----------------------------------------------------------------------===//
990 // Function Body / Expression rewriting
991 //===----------------------------------------------------------------------===//
993 Stmt
*RewriteBlocks::RewriteFunctionBody(Stmt
*S
) {
994 // Start by rewriting all children.
995 for (Stmt::child_iterator CI
= S
->child_begin(), E
= S
->child_end();
998 if (BlockExpr
*CBE
= dyn_cast
<BlockExpr
>(*CI
)) {
999 Stmt
*newStmt
= RewriteFunctionBody(CBE
->getBody());
1003 // We've just rewritten the block body in place.
1004 // Now we snarf the rewritten text and stash it away for later use.
1005 std::string S
= Rewrite
.getRewritenText(CBE
->getSourceRange());
1006 RewrittenBlockExprs
[CBE
] = S
;
1007 std::string Init
= SynthesizeBlockInitExpr(CBE
);
1008 // Do the rewrite, using S.size() which contains the rewritten size.
1009 ReplaceText(CBE
->getLocStart(), S
.size(), Init
.c_str(), Init
.size());
1011 Stmt
*newStmt
= RewriteFunctionBody(*CI
);
1016 // Handle specific things.
1017 if (CallExpr
*CE
= dyn_cast
<CallExpr
>(S
)) {
1018 if (CE
->getCallee()->getType()->isBlockPointerType())
1019 RewriteBlockCall(CE
);
1021 if (CastExpr
*CE
= dyn_cast
<CastExpr
>(S
)) {
1022 RewriteCastExpr(CE
);
1024 if (DeclStmt
*DS
= dyn_cast
<DeclStmt
>(S
)) {
1025 for (DeclStmt::decl_iterator DI
= DS
->decl_begin(), DE
= DS
->decl_end();
1028 ScopedDecl
*SD
= *DI
;
1029 if (ValueDecl
*ND
= dyn_cast
<ValueDecl
>(SD
)) {
1030 if (isBlockPointerType(ND
->getType()))
1031 RewriteBlockPointerDecl(ND
);
1032 else if (ND
->getType()->isFunctionPointerType())
1033 CheckFunctionPointerDecl(ND
->getType(), ND
);
1035 if (TypedefDecl
*TD
= dyn_cast
<TypedefDecl
>(SD
)) {
1036 if (isBlockPointerType(TD
->getUnderlyingType()))
1037 RewriteBlockPointerDecl(TD
);
1038 else if (TD
->getUnderlyingType()->isFunctionPointerType())
1039 CheckFunctionPointerDecl(TD
->getUnderlyingType(), TD
);
1043 // Handle specific things.
1044 if (BlockDeclRefExpr
*BDRE
= dyn_cast
<BlockDeclRefExpr
>(S
)) {
1045 if (BDRE
->isByRef())
1046 RewriteBlockDeclRefExpr(BDRE
);
1048 // Return this stmt unmodified.
1052 void RewriteBlocks::RewriteFunctionTypeProto(QualType funcType
, NamedDecl
*D
) {
1053 if (FunctionTypeProto
*fproto
= dyn_cast
<FunctionTypeProto
>(funcType
)) {
1054 for (FunctionTypeProto::arg_type_iterator I
= fproto
->arg_type_begin(),
1055 E
= fproto
->arg_type_end(); I
&& (I
!= E
); ++I
)
1056 if (isBlockPointerType(*I
)) {
1057 // All the args are checked/rewritten. Don't call twice!
1058 RewriteBlockPointerDecl(D
);
1064 void RewriteBlocks::CheckFunctionPointerDecl(QualType funcType
, NamedDecl
*ND
) {
1065 const PointerType
*PT
= funcType
->getAsPointerType();
1066 if (PT
&& PointerTypeTakesAnyBlockArguments(funcType
))
1067 RewriteFunctionTypeProto(PT
->getPointeeType(), ND
);
1070 /// HandleDeclInMainFile - This is called for each top-level decl defined in the
1071 /// main file of the input.
1072 void RewriteBlocks::HandleDeclInMainFile(Decl
*D
) {
1073 if (FunctionDecl
*FD
= dyn_cast
<FunctionDecl
>(D
)) {
1074 // Since function prototypes don't have ParmDecl's, we check the function
1075 // prototype. This enables us to rewrite function declarations and
1076 // definitions using the same code.
1077 RewriteFunctionTypeProto(FD
->getType(), FD
);
1079 if (Stmt
*Body
= FD
->getBody()) {
1080 CurFunctionDef
= FD
;
1081 FD
->setBody(RewriteFunctionBody(Body
));
1082 // This synthesizes and inserts the block "impl" struct, invoke function,
1083 // and any copy/dispose helper functions.
1084 InsertBlockLiteralsWithinFunction(FD
);
1089 if (ObjCMethodDecl
*MD
= dyn_cast
<ObjCMethodDecl
>(D
)) {
1090 RewriteMethodDecl(MD
);
1091 if (Stmt
*Body
= MD
->getBody()) {
1093 RewriteFunctionBody(Body
);
1094 InsertBlockLiteralsWithinMethod(MD
);
1098 if (VarDecl
*VD
= dyn_cast
<VarDecl
>(D
)) {
1099 if (isBlockPointerType(VD
->getType())) {
1100 RewriteBlockPointerDecl(VD
);
1101 if (VD
->getInit()) {
1102 if (BlockExpr
*CBE
= dyn_cast
<BlockExpr
>(VD
->getInit())) {
1103 RewriteFunctionBody(CBE
->getBody());
1105 // We've just rewritten the block body in place.
1106 // Now we snarf the rewritten text and stash it away for later use.
1107 std::string S
= Rewrite
.getRewritenText(CBE
->getSourceRange());
1108 RewrittenBlockExprs
[CBE
] = S
;
1109 std::string Init
= SynthesizeBlockInitExpr(CBE
, VD
);
1110 // Do the rewrite, using S.size() which contains the rewritten size.
1111 ReplaceText(CBE
->getLocStart(), S
.size(), Init
.c_str(), Init
.size());
1112 SynthesizeBlockLiterals(VD
->getTypeSpecStartLoc(), VD
->getName());
1113 } else if (CastExpr
*CE
= dyn_cast
<CastExpr
>(VD
->getInit())) {
1114 RewriteCastExpr(CE
);
1117 } else if (VD
->getType()->isFunctionPointerType()) {
1118 CheckFunctionPointerDecl(VD
->getType(), VD
);
1119 if (VD
->getInit()) {
1120 if (CastExpr
*CE
= dyn_cast
<CastExpr
>(VD
->getInit())) {
1121 RewriteCastExpr(CE
);
1127 if (TypedefDecl
*TD
= dyn_cast
<TypedefDecl
>(D
)) {
1128 if (isBlockPointerType(TD
->getUnderlyingType()))
1129 RewriteBlockPointerDecl(TD
);
1130 else if (TD
->getUnderlyingType()->isFunctionPointerType())
1131 CheckFunctionPointerDecl(TD
->getUnderlyingType(), TD
);
1134 if (RecordDecl
*RD
= dyn_cast
<RecordDecl
>(D
)) {
1135 if (RD
->isDefinition()) {
1136 for (RecordDecl::field_const_iterator i
= RD
->field_begin(),
1137 e
= RD
->field_end(); i
!= e
; ++i
) {
1139 if (isBlockPointerType(FD
->getType()))
1140 RewriteBlockPointerDecl(FD
);