[cfe-commits] r92014 - in /cfe/trunk: include/clang/Driver/CC1Options.td include/clang/Frontend/ASTConsumers.h include/clang/Frontend/FrontendActions.h include/clang/Frontend/FrontendOptions.h lib/Frontend/CMakeLists.txt lib/Frontend/CompilerInvocation.cpp lib/Frontend/FrontendActions.cpp lib/Frontend/RewriteBlocks.cpp test/Rewriter/block-test.c tools/driver/cc1_main.cpp
Kovarththanan Rajaratnam
kovarththanan.rajaratnam at gmail.com
Wed Dec 23 10:03:34 PST 2009
Author: krj
Date: Wed Dec 23 12:03:34 2009
New Revision: 92014
URL: http://llvm.org/viewvc/llvm-project?rev=92014&view=rev
Log:
Remove RewriteBlocks. It has been superseded by RewriteObjC
Removed:
cfe/trunk/lib/Frontend/RewriteBlocks.cpp
cfe/trunk/test/Rewriter/block-test.c
Modified:
cfe/trunk/include/clang/Driver/CC1Options.td
cfe/trunk/include/clang/Frontend/ASTConsumers.h
cfe/trunk/include/clang/Frontend/FrontendActions.h
cfe/trunk/include/clang/Frontend/FrontendOptions.h
cfe/trunk/lib/Frontend/CMakeLists.txt
cfe/trunk/lib/Frontend/CompilerInvocation.cpp
cfe/trunk/lib/Frontend/FrontendActions.cpp
cfe/trunk/tools/driver/cc1_main.cpp
Modified: cfe/trunk/include/clang/Driver/CC1Options.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Driver/CC1Options.td?rev=92014&r1=92013&r2=92014&view=diff
==============================================================================
--- cfe/trunk/include/clang/Driver/CC1Options.td (original)
+++ cfe/trunk/include/clang/Driver/CC1Options.td Wed Dec 23 12:03:34 2009
@@ -284,8 +284,6 @@
HelpText<"Rewrite ObjC into C (code rewriter example)">;
def rewrite_macros : Flag<"-rewrite-macros">,
HelpText<"Expand macros without full preprocessing">;
-def rewrite_blocks : Flag<"-rewrite-blocks">,
- HelpText<"Rewrite Blocks to C">;
}
Modified: cfe/trunk/include/clang/Frontend/ASTConsumers.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Frontend/ASTConsumers.h?rev=92014&r1=92013&r2=92014&view=diff
==============================================================================
--- cfe/trunk/include/clang/Frontend/ASTConsumers.h (original)
+++ cfe/trunk/include/clang/Frontend/ASTConsumers.h Wed Dec 23 12:03:34 2009
@@ -101,12 +101,6 @@
llvm::raw_ostream *OS,
const char *isysroot = 0);
-// Block rewriter: rewrites code using the Apple blocks extension to pure
-// C code. Output is always sent to stdout.
-ASTConsumer *CreateBlockRewriter(const std::string &InFile,
- Diagnostic &Diags,
- const LangOptions &LangOpts);
-
// Inheritance viewer: for C++ code, creates a graph of the inheritance
// tree for the given class and displays it with "dotty".
ASTConsumer *CreateInheritanceViewer(const std::string& clsname);
Modified: cfe/trunk/include/clang/Frontend/FrontendActions.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Frontend/FrontendActions.h?rev=92014&r1=92013&r2=92014&view=diff
==============================================================================
--- cfe/trunk/include/clang/Frontend/FrontendActions.h (original)
+++ cfe/trunk/include/clang/Frontend/FrontendActions.h Wed Dec 23 12:03:34 2009
@@ -110,12 +110,6 @@
llvm::StringRef InFile);
};
-class RewriteBlocksAction : public ASTFrontendAction {
-protected:
- virtual ASTConsumer *CreateASTConsumer(CompilerInstance &CI,
- llvm::StringRef InFile);
-};
-
class SyntaxOnlyAction : public ASTFrontendAction {
protected:
virtual ASTConsumer *CreateASTConsumer(CompilerInstance &CI,
Modified: cfe/trunk/include/clang/Frontend/FrontendOptions.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Frontend/FrontendOptions.h?rev=92014&r1=92013&r2=92014&view=diff
==============================================================================
--- cfe/trunk/include/clang/Frontend/FrontendOptions.h (original)
+++ cfe/trunk/include/clang/Frontend/FrontendOptions.h Wed Dec 23 12:03:34 2009
@@ -41,7 +41,6 @@
PluginAction, ///< Run a plugin action, \see ActionName.
PrintDeclContext, ///< Print DeclContext and their Decls.
PrintPreprocessedInput, ///< -E mode.
- RewriteBlocks, ///< ObjC->C Rewriter for Blocks.
RewriteMacros, ///< Expand macros but not #includes.
RewriteObjC, ///< ObjC->C Rewriter.
RewriteTest, ///< Rewriter playground
Modified: cfe/trunk/lib/Frontend/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/CMakeLists.txt?rev=92014&r1=92013&r2=92014&view=diff
==============================================================================
--- cfe/trunk/lib/Frontend/CMakeLists.txt (original)
+++ cfe/trunk/lib/Frontend/CMakeLists.txt Wed Dec 23 12:03:34 2009
@@ -31,7 +31,6 @@
PlistDiagnostics.cpp
PrintParserCallbacks.cpp
PrintPreprocessedOutput.cpp
- RewriteBlocks.cpp
RewriteMacros.cpp
RewriteObjC.cpp
RewriteTest.cpp
Modified: cfe/trunk/lib/Frontend/CompilerInvocation.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/CompilerInvocation.cpp?rev=92014&r1=92013&r2=92014&view=diff
==============================================================================
--- cfe/trunk/lib/Frontend/CompilerInvocation.cpp (original)
+++ cfe/trunk/lib/Frontend/CompilerInvocation.cpp Wed Dec 23 12:03:34 2009
@@ -280,7 +280,6 @@
case frontend::ParseSyntaxOnly: return "-fsyntax-only";
case frontend::PrintDeclContext: return "-print-decl-contexts";
case frontend::PrintPreprocessedInput: return "-E";
- case frontend::RewriteBlocks: return "-rewrite-blocks";
case frontend::RewriteMacros: return "-rewrite-macros";
case frontend::RewriteObjC: return "-rewrite-objc";
case frontend::RewriteTest: return "-rewrite-test";
@@ -858,8 +857,6 @@
Opts.ProgramAction = frontend::PrintDeclContext; break;
case OPT_E:
Opts.ProgramAction = frontend::PrintPreprocessedInput; break;
- case OPT_rewrite_blocks:
- Opts.ProgramAction = frontend::RewriteBlocks; break;
case OPT_rewrite_macros:
Opts.ProgramAction = frontend::RewriteMacros; break;
case OPT_rewrite_objc:
Modified: cfe/trunk/lib/Frontend/FrontendActions.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/FrontendActions.cpp?rev=92014&r1=92013&r2=92014&view=diff
==============================================================================
--- cfe/trunk/lib/Frontend/FrontendActions.cpp (original)
+++ cfe/trunk/lib/Frontend/FrontendActions.cpp Wed Dec 23 12:03:34 2009
@@ -154,11 +154,6 @@
return 0;
}
-ASTConsumer *RewriteBlocksAction::CreateASTConsumer(CompilerInstance &CI,
- llvm::StringRef InFile) {
- return CreateBlockRewriter(InFile, CI.getDiagnostics(), CI.getLangOpts());
-}
-
ASTConsumer *SyntaxOnlyAction::CreateASTConsumer(CompilerInstance &CI,
llvm::StringRef InFile) {
return new ASTConsumer();
Removed: cfe/trunk/lib/Frontend/RewriteBlocks.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/RewriteBlocks.cpp?rev=92013&view=auto
==============================================================================
--- cfe/trunk/lib/Frontend/RewriteBlocks.cpp (original)
+++ cfe/trunk/lib/Frontend/RewriteBlocks.cpp (removed)
@@ -1,1152 +0,0 @@
-//===--- RewriteBlocks.cpp ----------------------------------------------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// Hacks and fun related to the closure rewriter.
-//
-//===----------------------------------------------------------------------===//
-
-#include "clang/Frontend/ASTConsumers.h"
-#include "clang/Rewrite/Rewriter.h"
-#include "clang/AST/AST.h"
-#include "clang/AST/ASTConsumer.h"
-#include "clang/Basic/SourceManager.h"
-#include "clang/Basic/IdentifierTable.h"
-#include "clang/Basic/Diagnostic.h"
-#include "clang/Basic/LangOptions.h"
-#include "llvm/Support/MemoryBuffer.h"
-#include "llvm/ADT/StringExtras.h"
-#include "llvm/ADT/SmallPtrSet.h"
-
-using namespace clang;
-using llvm::utostr;
-
-namespace {
-
-class RewriteBlocks : public ASTConsumer {
- Rewriter Rewrite;
- Diagnostic &Diags;
- const LangOptions &LangOpts;
- unsigned RewriteFailedDiag;
-
- ASTContext *Context;
- SourceManager *SM;
- FileID MainFileID;
- const char *MainFileStart, *MainFileEnd;
-
- // Block expressions.
- llvm::SmallVector<BlockExpr *, 32> Blocks;
- llvm::SmallVector<BlockDeclRefExpr *, 32> BlockDeclRefs;
- llvm::DenseMap<BlockDeclRefExpr *, CallExpr *> BlockCallExprs;
-
- // Block related declarations.
- llvm::SmallPtrSet<ValueDecl *, 8> BlockByCopyDecls;
- llvm::SmallPtrSet<ValueDecl *, 8> BlockByRefDecls;
- llvm::SmallPtrSet<ValueDecl *, 8> ImportedBlockDecls;
-
- llvm::DenseMap<BlockExpr *, std::string> RewrittenBlockExprs;
-
- // The function/method we are rewriting.
- FunctionDecl *CurFunctionDef;
- ObjCMethodDecl *CurMethodDef;
-
- bool IsHeader;
-
- std::string Preamble;
-public:
- RewriteBlocks(std::string inFile, Diagnostic &D,
- const LangOptions &LOpts);
- ~RewriteBlocks() {
- // Get the buffer corresponding to MainFileID.
- // If we haven't changed it, then we are done.
- if (const RewriteBuffer *RewriteBuf =
- Rewrite.getRewriteBufferFor(MainFileID)) {
- std::string S(RewriteBuf->begin(), RewriteBuf->end());
- printf("%s\n", S.c_str());
- } else {
- printf("No changes\n");
- }
- }
-
- void Initialize(ASTContext &context);
-
- void InsertText(SourceLocation Loc, const char *StrData, unsigned StrLen);
- void ReplaceText(SourceLocation Start, unsigned OrigLength,
- const char *NewStr, unsigned NewLength);
-
- // Top Level Driver code.
- virtual void HandleTopLevelDecl(DeclGroupRef D) {
- for (DeclGroupRef::iterator I = D.begin(), E = D.end(); I != E; ++I)
- HandleTopLevelSingleDecl(*I);
- }
- void HandleTopLevelSingleDecl(Decl *D);
- void HandleDeclInMainFile(Decl *D);
-
- // Top level
- Stmt *RewriteFunctionBody(Stmt *S);
- void InsertBlockLiteralsWithinFunction(FunctionDecl *FD);
- void InsertBlockLiteralsWithinMethod(ObjCMethodDecl *MD);
-
- // Block specific rewrite rules.
- std::string SynthesizeBlockInitExpr(BlockExpr *Exp, VarDecl *VD=0);
-
- void RewriteBlockCall(CallExpr *Exp);
- void RewriteBlockPointerDecl(NamedDecl *VD);
- void RewriteBlockDeclRefExpr(BlockDeclRefExpr *VD);
- void RewriteBlockPointerFunctionArgs(FunctionDecl *FD);
-
- std::string SynthesizeBlockHelperFuncs(BlockExpr *CE, int i,
- const char *funcName, std::string Tag);
- std::string SynthesizeBlockFunc(BlockExpr *CE, int i,
- const char *funcName, std::string Tag);
- std::string SynthesizeBlockImpl(BlockExpr *CE, std::string Tag,
- bool hasCopyDisposeHelpers);
- std::string SynthesizeBlockCall(CallExpr *Exp);
- void SynthesizeBlockLiterals(SourceLocation FunLocStart,
- const char *FunName);
-
- void CollectBlockDeclRefInfo(BlockExpr *Exp);
- void GetBlockCallExprs(Stmt *S);
- void GetBlockDeclRefExprs(Stmt *S);
-
- // We avoid calling Type::isBlockPointerType(), since it operates on the
- // canonical type. We only care if the top-level type is a closure pointer.
- bool isBlockPointerType(QualType T) { return isa<BlockPointerType>(T); }
-
- // FIXME: This predicate seems like it would be useful to add to ASTContext.
- bool isObjCType(QualType T) {
- if (!LangOpts.ObjC1 && !LangOpts.ObjC2)
- return false;
-
- QualType OCT = Context->getCanonicalType(T).getUnqualifiedType();
-
- if (OCT == Context->getCanonicalType(Context->getObjCIdType()) ||
- OCT == Context->getCanonicalType(Context->getObjCClassType()))
- return true;
-
- if (const PointerType *PT = OCT->getAs<PointerType>()) {
- if (isa<ObjCInterfaceType>(PT->getPointeeType()) ||
- PT->getPointeeType()->isObjCQualifiedIdType())
- return true;
- }
- return false;
- }
- // ObjC rewrite methods.
- void RewriteInterfaceDecl(ObjCInterfaceDecl *ClassDecl);
- void RewriteCategoryDecl(ObjCCategoryDecl *CatDecl);
- void RewriteProtocolDecl(ObjCProtocolDecl *PDecl);
- void RewriteMethodDecl(ObjCMethodDecl *MDecl);
-
- void RewriteFunctionProtoType(QualType funcType, NamedDecl *D);
- void CheckFunctionPointerDecl(QualType dType, NamedDecl *ND);
- void RewriteCastExpr(CastExpr *CE);
-
- bool PointerTypeTakesAnyBlockArguments(QualType QT);
- void GetExtentOfArgList(const char *Name, const char *&LParen, const char *&RParen);
-};
-
-}
-
-static bool IsHeaderFile(const std::string &Filename) {
- std::string::size_type DotPos = Filename.rfind('.');
-
- if (DotPos == std::string::npos) {
- // no file extension
- return false;
- }
-
- std::string Ext = std::string(Filename.begin()+DotPos+1, Filename.end());
- // C header: .h
- // C++ header: .hh or .H;
- return Ext == "h" || Ext == "hh" || Ext == "H";
-}
-
-RewriteBlocks::RewriteBlocks(std::string inFile,
- Diagnostic &D, const LangOptions &LOpts) :
- Diags(D), LangOpts(LOpts) {
- IsHeader = IsHeaderFile(inFile);
- CurFunctionDef = 0;
- CurMethodDef = 0;
- RewriteFailedDiag = Diags.getCustomDiagID(Diagnostic::Warning,
- "rewriting failed");
-}
-
-ASTConsumer *clang::CreateBlockRewriter(const std::string& InFile,
- Diagnostic &Diags,
- const LangOptions &LangOpts) {
- return new RewriteBlocks(InFile, Diags, LangOpts);
-}
-
-void RewriteBlocks::Initialize(ASTContext &context) {
- Context = &context;
- SM = &Context->getSourceManager();
-
- // Get the ID and start/end of the main file.
- MainFileID = SM->getMainFileID();
- const llvm::MemoryBuffer *MainBuf = SM->getBuffer(MainFileID);
- MainFileStart = MainBuf->getBufferStart();
- MainFileEnd = MainBuf->getBufferEnd();
-
- Rewrite.setSourceMgr(Context->getSourceManager(), LangOpts);
-
- if (IsHeader)
- Preamble = "#pragma once\n";
- Preamble += "#ifndef BLOCK_IMPL\n";
- Preamble += "#define BLOCK_IMPL\n";
- Preamble += "struct __block_impl {\n";
- Preamble += " void *isa;\n";
- Preamble += " int Flags;\n";
- Preamble += " int Size;\n";
- Preamble += " void *FuncPtr;\n";
- Preamble += "};\n";
- Preamble += "enum {\n";
- Preamble += " BLOCK_HAS_COPY_DISPOSE = (1<<25),\n";
- Preamble += " BLOCK_IS_GLOBAL = (1<<28)\n";
- Preamble += "};\n";
- if (LangOpts.Microsoft)
- Preamble += "#define __OBJC_RW_EXTERN extern \"C\" __declspec(dllimport)\n";
- else
- Preamble += "#define __OBJC_RW_EXTERN extern\n";
- Preamble += "// Runtime copy/destroy helper functions\n";
- Preamble += "__OBJC_RW_EXTERN void _Block_copy_assign(void *, void *);\n";
- Preamble += "__OBJC_RW_EXTERN void _Block_byref_assign_copy(void *, void *);\n";
- Preamble += "__OBJC_RW_EXTERN void _Block_destroy(void *);\n";
- Preamble += "__OBJC_RW_EXTERN void _Block_byref_release(void *);\n";
- Preamble += "__OBJC_RW_EXTERN void *_NSConcreteGlobalBlock;\n";
- Preamble += "__OBJC_RW_EXTERN void *_NSConcreteStackBlock;\n";
- Preamble += "#endif\n";
-
- InsertText(SM->getLocForStartOfFile(MainFileID),
- Preamble.c_str(), Preamble.size());
-}
-
-void RewriteBlocks::InsertText(SourceLocation Loc, const char *StrData,
- unsigned StrLen) {
- if (!Rewrite.InsertText(Loc, StrData, StrLen))
- return;
- Diags.Report(Context->getFullLoc(Loc), RewriteFailedDiag);
-}
-
-void RewriteBlocks::ReplaceText(SourceLocation Start, unsigned OrigLength,
- const char *NewStr, unsigned NewLength) {
- if (!Rewrite.ReplaceText(Start, OrigLength,
- llvm::StringRef(NewStr, NewLength)))
- return;
- Diags.Report(Context->getFullLoc(Start), RewriteFailedDiag);
-}
-
-void RewriteBlocks::RewriteMethodDecl(ObjCMethodDecl *Method) {
- bool haveBlockPtrs = false;
- for (ObjCMethodDecl::param_iterator I = Method->param_begin(),
- E = Method->param_end(); I != E; ++I)
- if (isBlockPointerType((*I)->getType()))
- haveBlockPtrs = true;
-
- if (!haveBlockPtrs)
- return;
-
- // Do a fuzzy rewrite.
- // We have 1 or more arguments that have closure pointers.
- SourceLocation Loc = Method->getLocStart();
- SourceLocation LocEnd = Method->getLocEnd();
- const char *startBuf = SM->getCharacterData(Loc);
- const char *endBuf = SM->getCharacterData(LocEnd);
-
- const char *methodPtr = startBuf;
- std::string Tag = "struct __block_impl *";
-
- while (*methodPtr++ && (methodPtr != endBuf)) {
- switch (*methodPtr) {
- case ':':
- methodPtr++;
- if (*methodPtr == '(') {
- const char *scanType = ++methodPtr;
- bool foundBlockPointer = false;
- unsigned parenCount = 1;
-
- while (parenCount) {
- switch (*scanType) {
- case '(':
- parenCount++;
- break;
- case ')':
- parenCount--;
- break;
- case '^':
- foundBlockPointer = true;
- break;
- }
- scanType++;
- }
- if (foundBlockPointer) {
- // advance the location to startArgList.
- Loc = Loc.getFileLocWithOffset(methodPtr-startBuf);
- assert((Loc.isValid()) && "Invalid Loc");
- ReplaceText(Loc, scanType-methodPtr-1, Tag.c_str(), Tag.size());
-
- // Advance startBuf. Since the underlying buffer has changed,
- // it's very important to advance startBuf (so we can correctly
- // compute a relative Loc the next time around).
- startBuf = methodPtr;
- }
- // Advance the method ptr to the end of the type.
- methodPtr = scanType;
- }
- break;
- }
- }
- return;
-}
-
-void RewriteBlocks::RewriteInterfaceDecl(ObjCInterfaceDecl *ClassDecl) {
- for (ObjCInterfaceDecl::instmeth_iterator
- I = ClassDecl->instmeth_begin(), E = ClassDecl->instmeth_end();
- I != E; ++I)
- RewriteMethodDecl(*I);
- for (ObjCInterfaceDecl::classmeth_iterator
- I = ClassDecl->classmeth_begin(), E = ClassDecl->classmeth_end();
- I != E; ++I)
- RewriteMethodDecl(*I);
-}
-
-void RewriteBlocks::RewriteCategoryDecl(ObjCCategoryDecl *CatDecl) {
- for (ObjCCategoryDecl::instmeth_iterator
- I = CatDecl->instmeth_begin(), E = CatDecl->instmeth_end();
- I != E; ++I)
- RewriteMethodDecl(*I);
- for (ObjCCategoryDecl::classmeth_iterator
- I = CatDecl->classmeth_begin(), E = CatDecl->classmeth_end();
- I != E; ++I)
- RewriteMethodDecl(*I);
-}
-
-void RewriteBlocks::RewriteProtocolDecl(ObjCProtocolDecl *PDecl) {
- for (ObjCProtocolDecl::instmeth_iterator
- I = PDecl->instmeth_begin(), E = PDecl->instmeth_end();
- I != E; ++I)
- RewriteMethodDecl(*I);
- for (ObjCProtocolDecl::classmeth_iterator
- I = PDecl->classmeth_begin(), E = PDecl->classmeth_end();
- I != E; ++I)
- RewriteMethodDecl(*I);
-}
-
-//===----------------------------------------------------------------------===//
-// Top Level Driver Code
-//===----------------------------------------------------------------------===//
-
-void RewriteBlocks::HandleTopLevelSingleDecl(Decl *D) {
- // Two cases: either the decl could be in the main file, or it could be in a
- // #included file. If the former, rewrite it now. If the later, check to see
- // if we rewrote the #include/#import.
- SourceLocation Loc = D->getLocation();
- Loc = SM->getInstantiationLoc(Loc);
-
- // If this is for a builtin, ignore it.
- if (Loc.isInvalid()) return;
-
- if (ObjCInterfaceDecl *MD = dyn_cast<ObjCInterfaceDecl>(D))
- RewriteInterfaceDecl(MD);
- else if (ObjCCategoryDecl *CD = dyn_cast<ObjCCategoryDecl>(D))
- RewriteCategoryDecl(CD);
- else if (ObjCProtocolDecl *PD = dyn_cast<ObjCProtocolDecl>(D))
- RewriteProtocolDecl(PD);
-
- // If we have a decl in the main file, see if we should rewrite it.
- if (SM->isFromMainFile(Loc))
- HandleDeclInMainFile(D);
- return;
-}
-
-std::string RewriteBlocks::SynthesizeBlockFunc(BlockExpr *CE, int i,
- const char *funcName,
- std::string Tag) {
- const FunctionType *AFT = CE->getFunctionType();
- QualType RT = AFT->getResultType();
- std::string StructRef = "struct " + Tag;
- std::string S = "static " + RT.getAsString() + " __" +
- funcName + "_" + "block_func_" + utostr(i);
-
- BlockDecl *BD = CE->getBlockDecl();
-
- if (isa<FunctionNoProtoType>(AFT)) {
- S += "()";
- } else if (BD->param_empty()) {
- S += "(" + StructRef + " *__cself)";
- } else {
- const FunctionProtoType *FT = cast<FunctionProtoType>(AFT);
- assert(FT && "SynthesizeBlockFunc: No function proto");
- S += '(';
- // first add the implicit argument.
- S += StructRef + " *__cself, ";
- std::string ParamStr;
- for (BlockDecl::param_iterator AI = BD->param_begin(),
- E = BD->param_end(); AI != E; ++AI) {
- if (AI != BD->param_begin()) S += ", ";
- ParamStr = (*AI)->getNameAsString();
- (*AI)->getType().getAsStringInternal(ParamStr, Context->PrintingPolicy);
- S += ParamStr;
- }
- if (FT->isVariadic()) {
- if (!BD->param_empty()) S += ", ";
- S += "...";
- }
- S += ')';
- }
- S += " {\n";
-
- // Create local declarations to avoid rewriting all closure decl ref exprs.
- // First, emit a declaration for all "by ref" decls.
- for (llvm::SmallPtrSet<ValueDecl*,8>::iterator I = BlockByRefDecls.begin(),
- E = BlockByRefDecls.end(); I != E; ++I) {
- S += " ";
- std::string Name = (*I)->getNameAsString();
- Context->getPointerType((*I)->getType()).getAsStringInternal(Name,
- Context->PrintingPolicy);
- S += Name + " = __cself->" + (*I)->getNameAsString() + "; // bound by ref\n";
- }
- // Next, emit a declaration for all "by copy" declarations.
- for (llvm::SmallPtrSet<ValueDecl*,8>::iterator I = BlockByCopyDecls.begin(),
- E = BlockByCopyDecls.end(); I != E; ++I) {
- S += " ";
- std::string Name = (*I)->getNameAsString();
- // Handle nested closure invocation. For example:
- //
- // void (^myImportedClosure)(void);
- // myImportedClosure = ^(void) { setGlobalInt(x + y); };
- //
- // void (^anotherClosure)(void);
- // anotherClosure = ^(void) {
- // myImportedClosure(); // import and invoke the closure
- // };
- //
- if (isBlockPointerType((*I)->getType()))
- S += "struct __block_impl *";
- else
- (*I)->getType().getAsStringInternal(Name, Context->PrintingPolicy);
- S += Name + " = __cself->" + (*I)->getNameAsString() + "; // bound by copy\n";
- }
- std::string RewrittenStr = RewrittenBlockExprs[CE];
- const char *cstr = RewrittenStr.c_str();
- while (*cstr++ != '{') ;
- S += cstr;
- S += "\n";
- return S;
-}
-
-std::string RewriteBlocks::SynthesizeBlockHelperFuncs(BlockExpr *CE, int i,
- const char *funcName,
- std::string Tag) {
- std::string StructRef = "struct " + Tag;
- std::string S = "static void __";
-
- S += funcName;
- S += "_block_copy_" + utostr(i);
- S += "(" + StructRef;
- S += "*dst, " + StructRef;
- S += "*src) {";
- for (llvm::SmallPtrSet<ValueDecl*,8>::iterator I = ImportedBlockDecls.begin(),
- E = ImportedBlockDecls.end(); I != E; ++I) {
- S += "_Block_copy_assign(&dst->";
- S += (*I)->getNameAsString();
- S += ", src->";
- S += (*I)->getNameAsString();
- S += ");}";
- }
- S += "\nstatic void __";
- S += funcName;
- S += "_block_dispose_" + utostr(i);
- S += "(" + StructRef;
- S += "*src) {";
- for (llvm::SmallPtrSet<ValueDecl*,8>::iterator I = ImportedBlockDecls.begin(),
- E = ImportedBlockDecls.end(); I != E; ++I) {
- S += "_Block_destroy(src->";
- S += (*I)->getNameAsString();
- S += ");";
- }
- S += "}\n";
- return S;
-}
-
-std::string RewriteBlocks::SynthesizeBlockImpl(BlockExpr *CE, std::string Tag,
- bool hasCopyDisposeHelpers) {
- std::string S = "struct " + Tag;
- std::string Constructor = " " + Tag;
-
- S += " {\n struct __block_impl impl;\n";
-
- if (hasCopyDisposeHelpers)
- S += " void *copy;\n void *dispose;\n";
-
- Constructor += "(void *fp";
-
- if (hasCopyDisposeHelpers)
- Constructor += ", void *copyHelp, void *disposeHelp";
-
- if (BlockDeclRefs.size()) {
- // Output all "by copy" declarations.
- for (llvm::SmallPtrSet<ValueDecl*,8>::iterator I = BlockByCopyDecls.begin(),
- E = BlockByCopyDecls.end(); I != E; ++I) {
- S += " ";
- std::string FieldName = (*I)->getNameAsString();
- std::string ArgName = "_" + FieldName;
- // Handle nested closure invocation. For example:
- //
- // void (^myImportedBlock)(void);
- // myImportedBlock = ^(void) { setGlobalInt(x + y); };
- //
- // void (^anotherBlock)(void);
- // anotherBlock = ^(void) {
- // myImportedBlock(); // import and invoke the closure
- // };
- //
- if (isBlockPointerType((*I)->getType())) {
- S += "struct __block_impl *";
- Constructor += ", void *" + ArgName;
- } else {
- (*I)->getType().getAsStringInternal(FieldName, Context->PrintingPolicy);
- (*I)->getType().getAsStringInternal(ArgName, Context->PrintingPolicy);
- Constructor += ", " + ArgName;
- }
- S += FieldName + ";\n";
- }
- // Output all "by ref" declarations.
- for (llvm::SmallPtrSet<ValueDecl*,8>::iterator I = BlockByRefDecls.begin(),
- E = BlockByRefDecls.end(); I != E; ++I) {
- S += " ";
- std::string FieldName = (*I)->getNameAsString();
- std::string ArgName = "_" + FieldName;
- // Handle nested closure invocation. For example:
- //
- // void (^myImportedBlock)(void);
- // myImportedBlock = ^(void) { setGlobalInt(x + y); };
- //
- // void (^anotherBlock)(void);
- // anotherBlock = ^(void) {
- // myImportedBlock(); // import and invoke the closure
- // };
- //
- if (isBlockPointerType((*I)->getType())) {
- S += "struct __block_impl *";
- Constructor += ", void *" + ArgName;
- } else {
- Context->getPointerType((*I)->getType()).getAsStringInternal(FieldName,
- Context->PrintingPolicy);
- Context->getPointerType((*I)->getType()).getAsStringInternal(ArgName,
- Context->PrintingPolicy);
- Constructor += ", " + ArgName;
- }
- S += FieldName + "; // by ref\n";
- }
- // Finish writing the constructor.
- // FIXME: handle NSConcreteGlobalBlock.
- Constructor += ", int flags=0) {\n";
- Constructor += " impl.isa = 0/*&_NSConcreteStackBlock*/;\n impl.Size = sizeof(";
- Constructor += Tag + ");\n impl.Flags = flags;\n impl.FuncPtr = fp;\n";
-
- if (hasCopyDisposeHelpers)
- Constructor += " copy = copyHelp;\n dispose = disposeHelp;\n";
-
- // Initialize all "by copy" arguments.
- for (llvm::SmallPtrSet<ValueDecl*,8>::iterator I = BlockByCopyDecls.begin(),
- E = BlockByCopyDecls.end(); I != E; ++I) {
- std::string Name = (*I)->getNameAsString();
- Constructor += " ";
- if (isBlockPointerType((*I)->getType()))
- Constructor += Name + " = (struct __block_impl *)_";
- else
- Constructor += Name + " = _";
- Constructor += Name + ";\n";
- }
- // Initialize all "by ref" arguments.
- for (llvm::SmallPtrSet<ValueDecl*,8>::iterator I = BlockByRefDecls.begin(),
- E = BlockByRefDecls.end(); I != E; ++I) {
- std::string Name = (*I)->getNameAsString();
- Constructor += " ";
- if (isBlockPointerType((*I)->getType()))
- Constructor += Name + " = (struct __block_impl *)_";
- else
- Constructor += Name + " = _";
- Constructor += Name + ";\n";
- }
- } else {
- // Finish writing the constructor.
- // FIXME: handle NSConcreteGlobalBlock.
- Constructor += ", int flags=0) {\n";
- Constructor += " impl.isa = 0/*&_NSConcreteStackBlock*/;\n impl.Size = sizeof(";
- Constructor += Tag + ");\n impl.Flags = flags;\n impl.FuncPtr = fp;\n";
- if (hasCopyDisposeHelpers)
- Constructor += " copy = copyHelp;\n dispose = disposeHelp;\n";
- }
- Constructor += " ";
- Constructor += "}\n";
- S += Constructor;
- S += "};\n";
- return S;
-}
-
-void RewriteBlocks::SynthesizeBlockLiterals(SourceLocation FunLocStart,
- const char *FunName) {
- // Insert closures that were part of the function.
- for (unsigned i = 0; i < Blocks.size(); i++) {
-
- CollectBlockDeclRefInfo(Blocks[i]);
-
- std::string Tag = "__" + std::string(FunName) + "_block_impl_" + utostr(i);
-
- std::string CI = SynthesizeBlockImpl(Blocks[i], Tag,
- ImportedBlockDecls.size() > 0);
-
- InsertText(FunLocStart, CI.c_str(), CI.size());
-
- std::string CF = SynthesizeBlockFunc(Blocks[i], i, FunName, Tag);
-
- InsertText(FunLocStart, CF.c_str(), CF.size());
-
- if (ImportedBlockDecls.size()) {
- std::string HF = SynthesizeBlockHelperFuncs(Blocks[i], i, FunName, Tag);
- InsertText(FunLocStart, HF.c_str(), HF.size());
- }
-
- BlockDeclRefs.clear();
- BlockByRefDecls.clear();
- BlockByCopyDecls.clear();
- BlockCallExprs.clear();
- ImportedBlockDecls.clear();
- }
- Blocks.clear();
- RewrittenBlockExprs.clear();
-}
-
-void RewriteBlocks::InsertBlockLiteralsWithinFunction(FunctionDecl *FD) {
- SourceLocation FunLocStart = FD->getTypeSpecStartLoc();
- const char *FuncName = FD->getNameAsCString();
-
- SynthesizeBlockLiterals(FunLocStart, FuncName);
-}
-
-void RewriteBlocks::InsertBlockLiteralsWithinMethod(ObjCMethodDecl *MD) {
- SourceLocation FunLocStart = MD->getLocStart();
- std::string FuncName = MD->getSelector().getAsString();
- // Convert colons to underscores.
- std::string::size_type loc = 0;
- while ((loc = FuncName.find(":", loc)) != std::string::npos)
- FuncName.replace(loc, 1, "_");
-
- SynthesizeBlockLiterals(FunLocStart, FuncName.c_str());
-}
-
-void RewriteBlocks::GetBlockDeclRefExprs(Stmt *S) {
- for (Stmt::child_iterator CI = S->child_begin(), E = S->child_end();
- CI != E; ++CI)
- if (*CI) {
- if (BlockExpr *CBE = dyn_cast<BlockExpr>(*CI))
- GetBlockDeclRefExprs(CBE->getBody());
- else
- GetBlockDeclRefExprs(*CI);
- }
- // Handle specific things.
- if (BlockDeclRefExpr *CDRE = dyn_cast<BlockDeclRefExpr>(S))
- // FIXME: Handle enums.
- if (!isa<FunctionDecl>(CDRE->getDecl()))
- BlockDeclRefs.push_back(CDRE);
- return;
-}
-
-void RewriteBlocks::GetBlockCallExprs(Stmt *S) {
- for (Stmt::child_iterator CI = S->child_begin(), E = S->child_end();
- CI != E; ++CI)
- if (*CI) {
- if (BlockExpr *CBE = dyn_cast<BlockExpr>(*CI))
- GetBlockCallExprs(CBE->getBody());
- else
- GetBlockCallExprs(*CI);
- }
-
- if (CallExpr *CE = dyn_cast<CallExpr>(S)) {
- if (CE->getCallee()->getType()->isBlockPointerType()) {
- BlockCallExprs[dyn_cast<BlockDeclRefExpr>(CE->getCallee())] = CE;
- }
- }
- return;
-}
-
-std::string RewriteBlocks::SynthesizeBlockCall(CallExpr *Exp) {
- // Navigate to relevant type information.
- const char *closureName = 0;
- const BlockPointerType *CPT = 0;
-
- if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(Exp->getCallee())) {
- closureName = DRE->getDecl()->getNameAsCString();
- CPT = DRE->getType()->getAs<BlockPointerType>();
- } else if (BlockDeclRefExpr *CDRE = dyn_cast<BlockDeclRefExpr>(Exp->getCallee())) {
- closureName = CDRE->getDecl()->getNameAsCString();
- CPT = CDRE->getType()->getAs<BlockPointerType>();
- } else if (MemberExpr *MExpr = dyn_cast<MemberExpr>(Exp->getCallee())) {
- closureName = MExpr->getMemberDecl()->getNameAsCString();
- CPT = MExpr->getType()->getAs<BlockPointerType>();
- } else {
- assert(1 && "RewriteBlockClass: Bad type");
- }
- assert(CPT && "RewriteBlockClass: Bad type");
- const FunctionType *FT = CPT->getPointeeType()->getAs<FunctionType>();
- assert(FT && "RewriteBlockClass: Bad type");
- const FunctionProtoType *FTP = dyn_cast<FunctionProtoType>(FT);
- // FTP will be null for closures that don't take arguments.
-
- // Build a closure call - start with a paren expr to enforce precedence.
- std::string BlockCall = "(";
-
- // Synthesize the cast.
- BlockCall += "(" + Exp->getType().getAsString() + "(*)";
- BlockCall += "(struct __block_impl *";
- if (FTP) {
- for (FunctionProtoType::arg_type_iterator I = FTP->arg_type_begin(),
- E = FTP->arg_type_end(); I && (I != E); ++I)
- BlockCall += ", " + (*I).getAsString();
- }
- BlockCall += "))"; // close the argument list and paren expression.
-
- // Invoke the closure. We need to cast it since the declaration type is
- // bogus (it's a function pointer type)
- BlockCall += "((struct __block_impl *)";
- std::string closureExprBufStr;
- llvm::raw_string_ostream closureExprBuf(closureExprBufStr);
- Exp->getCallee()->printPretty(closureExprBuf, *Context, 0,
- PrintingPolicy(LangOpts));
- BlockCall += closureExprBuf.str();
- BlockCall += ")->FuncPtr)";
-
- // Add the arguments.
- BlockCall += "((struct __block_impl *)";
- BlockCall += closureExprBuf.str();
- for (CallExpr::arg_iterator I = Exp->arg_begin(),
- E = Exp->arg_end(); I != E; ++I) {
- std::string syncExprBufS;
- llvm::raw_string_ostream Buf(syncExprBufS);
- (*I)->printPretty(Buf, *Context, 0, PrintingPolicy(LangOpts));
- BlockCall += ", " + Buf.str();
- }
- return BlockCall;
-}
-
-void RewriteBlocks::RewriteBlockCall(CallExpr *Exp) {
- std::string BlockCall = SynthesizeBlockCall(Exp);
-
- const char *startBuf = SM->getCharacterData(Exp->getLocStart());
- const char *endBuf = SM->getCharacterData(Exp->getLocEnd());
-
- ReplaceText(Exp->getLocStart(), endBuf-startBuf,
- BlockCall.c_str(), BlockCall.size());
-}
-
-void RewriteBlocks::RewriteBlockDeclRefExpr(BlockDeclRefExpr *BDRE) {
- // FIXME: Add more elaborate code generation required by the ABI.
- InsertText(BDRE->getLocStart(), "*", 1);
-}
-
-void RewriteBlocks::RewriteCastExpr(CastExpr *CE) {
- SourceLocation LocStart = CE->getLocStart();
- SourceLocation LocEnd = CE->getLocEnd();
-
- if (!Rewriter::isRewritable(LocStart) || !Rewriter::isRewritable(LocEnd))
- return;
-
- const char *startBuf = SM->getCharacterData(LocStart);
- const char *endBuf = SM->getCharacterData(LocEnd);
-
- // advance the location to startArgList.
- const char *argPtr = startBuf;
-
- while (*argPtr++ && (argPtr < endBuf)) {
- switch (*argPtr) {
- case '^':
- // Replace the '^' with '*'.
- LocStart = LocStart.getFileLocWithOffset(argPtr-startBuf);
- ReplaceText(LocStart, 1, "*", 1);
- break;
- }
- }
- return;
-}
-
-void RewriteBlocks::RewriteBlockPointerFunctionArgs(FunctionDecl *FD) {
- SourceLocation DeclLoc = FD->getLocation();
- unsigned parenCount = 0;
-
- // We have 1 or more arguments that have closure pointers.
- const char *startBuf = SM->getCharacterData(DeclLoc);
- const char *startArgList = strchr(startBuf, '(');
-
- assert((*startArgList == '(') && "Rewriter fuzzy parser confused");
-
- parenCount++;
- // advance the location to startArgList.
- DeclLoc = DeclLoc.getFileLocWithOffset(startArgList-startBuf);
- assert((DeclLoc.isValid()) && "Invalid DeclLoc");
-
- const char *argPtr = startArgList;
-
- while (*argPtr++ && parenCount) {
- switch (*argPtr) {
- case '^':
- // Replace the '^' with '*'.
- DeclLoc = DeclLoc.getFileLocWithOffset(argPtr-startArgList);
- ReplaceText(DeclLoc, 1, "*", 1);
- break;
- case '(':
- parenCount++;
- break;
- case ')':
- parenCount--;
- break;
- }
- }
- return;
-}
-
-bool RewriteBlocks::PointerTypeTakesAnyBlockArguments(QualType QT) {
- const FunctionProtoType *FTP;
- const PointerType *PT = QT->getAs<PointerType>();
- if (PT) {
- FTP = PT->getPointeeType()->getAs<FunctionProtoType>();
- } else {
- const BlockPointerType *BPT = QT->getAs<BlockPointerType>();
- assert(BPT && "BlockPointerTypeTakeAnyBlockArguments(): not a block pointer type");
- FTP = BPT->getPointeeType()->getAs<FunctionProtoType>();
- }
- if (FTP) {
- for (FunctionProtoType::arg_type_iterator I = FTP->arg_type_begin(),
- E = FTP->arg_type_end(); I != E; ++I)
- if (isBlockPointerType(*I))
- return true;
- }
- return false;
-}
-
-void RewriteBlocks::GetExtentOfArgList(const char *Name,
- const char *&LParen, const char *&RParen) {
- const char *argPtr = strchr(Name, '(');
- assert((*argPtr == '(') && "Rewriter fuzzy parser confused");
-
- LParen = argPtr; // output the start.
- argPtr++; // skip past the left paren.
- unsigned parenCount = 1;
-
- while (*argPtr && parenCount) {
- switch (*argPtr) {
- case '(': parenCount++; break;
- case ')': parenCount--; break;
- default: break;
- }
- if (parenCount) argPtr++;
- }
- assert((*argPtr == ')') && "Rewriter fuzzy parser confused");
- RParen = argPtr; // output the end
-}
-
-void RewriteBlocks::RewriteBlockPointerDecl(NamedDecl *ND) {
- if (FunctionDecl *FD = dyn_cast<FunctionDecl>(ND)) {
- RewriteBlockPointerFunctionArgs(FD);
- return;
- }
- // Handle Variables and Typedefs.
- SourceLocation DeclLoc = ND->getLocation();
- QualType DeclT;
- if (VarDecl *VD = dyn_cast<VarDecl>(ND))
- DeclT = VD->getType();
- else if (TypedefDecl *TDD = dyn_cast<TypedefDecl>(ND))
- DeclT = TDD->getUnderlyingType();
- else if (FieldDecl *FD = dyn_cast<FieldDecl>(ND))
- DeclT = FD->getType();
- else
- assert(0 && "RewriteBlockPointerDecl(): Decl type not yet handled");
-
- const char *startBuf = SM->getCharacterData(DeclLoc);
- const char *endBuf = startBuf;
- // scan backward (from the decl location) for the end of the previous decl.
- while (*startBuf != '^' && *startBuf != ';' && startBuf != MainFileStart)
- startBuf--;
-
- // *startBuf != '^' if we are dealing with a pointer to function that
- // may take block argument types (which will be handled below).
- if (*startBuf == '^') {
- // Replace the '^' with '*', computing a negative offset.
- DeclLoc = DeclLoc.getFileLocWithOffset(startBuf-endBuf);
- ReplaceText(DeclLoc, 1, "*", 1);
- }
- if (PointerTypeTakesAnyBlockArguments(DeclT)) {
- // Replace the '^' with '*' for arguments.
- DeclLoc = ND->getLocation();
- startBuf = SM->getCharacterData(DeclLoc);
- const char *argListBegin, *argListEnd;
- GetExtentOfArgList(startBuf, argListBegin, argListEnd);
- while (argListBegin < argListEnd) {
- if (*argListBegin == '^') {
- SourceLocation CaretLoc = DeclLoc.getFileLocWithOffset(argListBegin-startBuf);
- ReplaceText(CaretLoc, 1, "*", 1);
- }
- argListBegin++;
- }
- }
- return;
-}
-
-void RewriteBlocks::CollectBlockDeclRefInfo(BlockExpr *Exp) {
- // Add initializers for any closure decl refs.
- GetBlockDeclRefExprs(Exp->getBody());
- if (BlockDeclRefs.size()) {
- // Unique all "by copy" declarations.
- for (unsigned i = 0; i < BlockDeclRefs.size(); i++)
- if (!BlockDeclRefs[i]->isByRef())
- BlockByCopyDecls.insert(BlockDeclRefs[i]->getDecl());
- // Unique all "by ref" declarations.
- for (unsigned i = 0; i < BlockDeclRefs.size(); i++)
- if (BlockDeclRefs[i]->isByRef()) {
- BlockByRefDecls.insert(BlockDeclRefs[i]->getDecl());
- }
- // Find any imported blocks...they will need special attention.
- for (unsigned i = 0; i < BlockDeclRefs.size(); i++)
- if (isBlockPointerType(BlockDeclRefs[i]->getType())) {
- GetBlockCallExprs(Blocks[i]);
- ImportedBlockDecls.insert(BlockDeclRefs[i]->getDecl());
- }
- }
-}
-
-std::string RewriteBlocks::SynthesizeBlockInitExpr(BlockExpr *Exp, VarDecl *VD) {
- Blocks.push_back(Exp);
-
- CollectBlockDeclRefInfo(Exp);
- std::string FuncName;
-
- if (CurFunctionDef)
- FuncName = std::string(CurFunctionDef->getNameAsString());
- else if (CurMethodDef) {
- FuncName = CurMethodDef->getSelector().getAsString();
- // Convert colons to underscores.
- std::string::size_type loc = 0;
- while ((loc = FuncName.find(":", loc)) != std::string::npos)
- FuncName.replace(loc, 1, "_");
- } else if (VD)
- FuncName = std::string(VD->getNameAsString());
-
- std::string BlockNumber = utostr(Blocks.size()-1);
-
- std::string Tag = "__" + FuncName + "_block_impl_" + BlockNumber;
- std::string Func = "__" + FuncName + "_block_func_" + BlockNumber;
-
- std::string FunkTypeStr;
-
- // Get a pointer to the function type so we can cast appropriately.
- Context->getPointerType(QualType(Exp->getFunctionType(),0))
- .getAsStringInternal(FunkTypeStr, Context->PrintingPolicy);
-
- // Rewrite the closure block with a compound literal. The first cast is
- // to prevent warnings from the C compiler.
- std::string Init = "(" + FunkTypeStr;
-
- Init += ")&" + Tag;
-
- // Initialize the block function.
- Init += "((void*)" + Func;
-
- if (ImportedBlockDecls.size()) {
- std::string Buf = "__" + FuncName + "_block_copy_" + BlockNumber;
- Init += ",(void*)" + Buf;
- Buf = "__" + FuncName + "_block_dispose_" + BlockNumber;
- Init += ",(void*)" + Buf;
- }
- // Add initializers for any closure decl refs.
- if (BlockDeclRefs.size()) {
- // Output all "by copy" declarations.
- for (llvm::SmallPtrSet<ValueDecl*,8>::iterator I = BlockByCopyDecls.begin(),
- E = BlockByCopyDecls.end(); I != E; ++I) {
- Init += ",";
- if (isObjCType((*I)->getType())) {
- Init += "[[";
- Init += (*I)->getNameAsString();
- Init += " retain] autorelease]";
- } else if (isBlockPointerType((*I)->getType())) {
- Init += "(void *)";
- Init += (*I)->getNameAsString();
- } else {
- Init += (*I)->getNameAsString();
- }
- }
- // Output all "by ref" declarations.
- for (llvm::SmallPtrSet<ValueDecl*,8>::iterator I = BlockByRefDecls.begin(),
- E = BlockByRefDecls.end(); I != E; ++I) {
- Init += ",&";
- Init += (*I)->getNameAsString();
- }
- }
- Init += ")";
- BlockDeclRefs.clear();
- BlockByRefDecls.clear();
- BlockByCopyDecls.clear();
- ImportedBlockDecls.clear();
-
- return Init;
-}
-
-//===----------------------------------------------------------------------===//
-// Function Body / Expression rewriting
-//===----------------------------------------------------------------------===//
-
-Stmt *RewriteBlocks::RewriteFunctionBody(Stmt *S) {
- // Start by rewriting all children.
- for (Stmt::child_iterator CI = S->child_begin(), E = S->child_end();
- CI != E; ++CI)
- if (*CI) {
- if (BlockExpr *CBE = dyn_cast<BlockExpr>(*CI)) {
- RewriteFunctionBody(CBE->getBody());
-
- // We've just rewritten the block body in place.
- // Now we snarf the rewritten text and stash it away for later use.
- std::string S = Rewrite.getRewritenText(CBE->getSourceRange());
- RewrittenBlockExprs[CBE] = S;
- std::string Init = SynthesizeBlockInitExpr(CBE);
- // Do the rewrite, using S.size() which contains the rewritten size.
- ReplaceText(CBE->getLocStart(), S.size(), Init.c_str(), Init.size());
- } else {
- RewriteFunctionBody(*CI);
- }
- }
- // Handle specific things.
- if (CallExpr *CE = dyn_cast<CallExpr>(S)) {
- if (CE->getCallee()->getType()->isBlockPointerType())
- RewriteBlockCall(CE);
- }
- if (CastExpr *CE = dyn_cast<CastExpr>(S)) {
- RewriteCastExpr(CE);
- }
- if (DeclStmt *DS = dyn_cast<DeclStmt>(S)) {
- for (DeclStmt::decl_iterator DI = DS->decl_begin(), DE = DS->decl_end();
- DI != DE; ++DI) {
-
- Decl *SD = *DI;
- if (ValueDecl *ND = dyn_cast<ValueDecl>(SD)) {
- if (isBlockPointerType(ND->getType()))
- RewriteBlockPointerDecl(ND);
- else if (ND->getType()->isFunctionPointerType())
- CheckFunctionPointerDecl(ND->getType(), ND);
- }
- if (TypedefDecl *TD = dyn_cast<TypedefDecl>(SD)) {
- if (isBlockPointerType(TD->getUnderlyingType()))
- RewriteBlockPointerDecl(TD);
- else if (TD->getUnderlyingType()->isFunctionPointerType())
- CheckFunctionPointerDecl(TD->getUnderlyingType(), TD);
- }
- }
- }
- // Handle specific things.
- if (BlockDeclRefExpr *BDRE = dyn_cast<BlockDeclRefExpr>(S)) {
- if (BDRE->isByRef())
- RewriteBlockDeclRefExpr(BDRE);
- }
- // Return this stmt unmodified.
- return S;
-}
-
-void RewriteBlocks::RewriteFunctionProtoType(QualType funcType, NamedDecl *D) {
- if (FunctionProtoType *fproto = dyn_cast<FunctionProtoType>(funcType)) {
- for (FunctionProtoType::arg_type_iterator I = fproto->arg_type_begin(),
- E = fproto->arg_type_end(); I && (I != E); ++I)
- if (isBlockPointerType(*I)) {
- // All the args are checked/rewritten. Don't call twice!
- RewriteBlockPointerDecl(D);
- break;
- }
- }
-}
-
-void RewriteBlocks::CheckFunctionPointerDecl(QualType funcType, NamedDecl *ND) {
- const PointerType *PT = funcType->getAs<PointerType>();
- if (PT && PointerTypeTakesAnyBlockArguments(funcType))
- RewriteFunctionProtoType(PT->getPointeeType(), ND);
-}
-
-/// HandleDeclInMainFile - This is called for each top-level decl defined in the
-/// main file of the input.
-void RewriteBlocks::HandleDeclInMainFile(Decl *D) {
- if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
- // Since function prototypes don't have ParmDecl's, we check the function
- // prototype. This enables us to rewrite function declarations and
- // definitions using the same code.
- RewriteFunctionProtoType(FD->getType(), FD);
-
- // FIXME: Handle CXXTryStmt
- if (CompoundStmt *Body = FD->getCompoundBody()) {
- CurFunctionDef = FD;
- FD->setBody(cast_or_null<CompoundStmt>(RewriteFunctionBody(Body)));
- // This synthesizes and inserts the block "impl" struct, invoke function,
- // and any copy/dispose helper functions.
- InsertBlockLiteralsWithinFunction(FD);
- CurFunctionDef = 0;
- }
- return;
- }
- if (ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D)) {
- RewriteMethodDecl(MD);
- if (Stmt *Body = MD->getBody()) {
- CurMethodDef = MD;
- RewriteFunctionBody(Body);
- InsertBlockLiteralsWithinMethod(MD);
- CurMethodDef = 0;
- }
- }
- if (VarDecl *VD = dyn_cast<VarDecl>(D)) {
- if (isBlockPointerType(VD->getType())) {
- RewriteBlockPointerDecl(VD);
- if (VD->getInit()) {
- if (BlockExpr *CBE = dyn_cast<BlockExpr>(VD->getInit())) {
- RewriteFunctionBody(CBE->getBody());
-
- // We've just rewritten the block body in place.
- // Now we snarf the rewritten text and stash it away for later use.
- std::string S = Rewrite.getRewritenText(CBE->getSourceRange());
- RewrittenBlockExprs[CBE] = S;
- std::string Init = SynthesizeBlockInitExpr(CBE, VD);
- // Do the rewrite, using S.size() which contains the rewritten size.
- ReplaceText(CBE->getLocStart(), S.size(), Init.c_str(), Init.size());
- SynthesizeBlockLiterals(VD->getTypeSpecStartLoc(),
- VD->getNameAsCString());
- } else if (CastExpr *CE = dyn_cast<CastExpr>(VD->getInit())) {
- RewriteCastExpr(CE);
- }
- }
- } else if (VD->getType()->isFunctionPointerType()) {
- CheckFunctionPointerDecl(VD->getType(), VD);
- if (VD->getInit()) {
- if (CastExpr *CE = dyn_cast<CastExpr>(VD->getInit())) {
- RewriteCastExpr(CE);
- }
- }
- }
- return;
- }
- if (TypedefDecl *TD = dyn_cast<TypedefDecl>(D)) {
- if (isBlockPointerType(TD->getUnderlyingType()))
- RewriteBlockPointerDecl(TD);
- else if (TD->getUnderlyingType()->isFunctionPointerType())
- CheckFunctionPointerDecl(TD->getUnderlyingType(), TD);
- return;
- }
- if (RecordDecl *RD = dyn_cast<RecordDecl>(D)) {
- if (RD->isDefinition()) {
- for (RecordDecl::field_iterator i = RD->field_begin(),
- e = RD->field_end(); i != e; ++i) {
- FieldDecl *FD = *i;
- if (isBlockPointerType(FD->getType()))
- RewriteBlockPointerDecl(FD);
- }
- }
- return;
- }
-}
Removed: cfe/trunk/test/Rewriter/block-test.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Rewriter/block-test.c?rev=92013&view=auto
==============================================================================
--- cfe/trunk/test/Rewriter/block-test.c (original)
+++ cfe/trunk/test/Rewriter/block-test.c (removed)
@@ -1,38 +0,0 @@
-// RUN: %clang_cc1 -rewrite-blocks %s -fblocks -o -
-
-static int (^block)(const void *, const void *) = (int (^)(const void *, const void *))0;
-static int (*func)(int (^block)(void *, void *)) = (int (*)(int (^block)(void *, void *)))0;
-
-typedef int (^block_T)(const void *, const void *);
-typedef int (*func_T)(int (^block)(void *, void *));
-
-void foo(const void *a, const void *b, void *c) {
- int (^block)(const void *, const void *) = (int (^)(const void *, const void *))c;
- int (*func)(int (^block)(void *, void *)) = (int (*)(int (^block)(void *, void *)))c;
-}
-
-typedef void (^test_block_t)();
-
-int main(int argc, char **argv) {
- int a;
-
- void (^test_block_v)();
- void (^test_block_v2)(int, float);
-
- void (^test_block_v3)(void (^barg)(int));
-
- a = 77;
- test_block_v = ^(){ int local=1; printf("a=%d\n",a+local); };
- test_block_v();
- a++;
- test_block_v();
-
- __block int b;
-
- b = 88;
- test_block_v2 = ^(int x, float f){ printf("b=%d\n",b); };
- test_block_v2(1,2.0);
- b++;
- test_block_v2(3,4.0);
- return 7;
-}
Modified: cfe/trunk/tools/driver/cc1_main.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/driver/cc1_main.cpp?rev=92014&r1=92013&r2=92014&view=diff
==============================================================================
--- cfe/trunk/tools/driver/cc1_main.cpp (original)
+++ cfe/trunk/tools/driver/cc1_main.cpp Wed Dec 23 12:03:34 2009
@@ -110,7 +110,6 @@
case PrintDeclContext: return new DeclContextPrintAction();
case PrintPreprocessedInput: return new PrintPreprocessedAction();
- case RewriteBlocks: return new RewriteBlocksAction();
case RewriteMacros: return new RewriteMacrosAction();
case RewriteObjC: return new RewriteObjCAction();
case RewriteTest: return new RewriteTestAction();
More information about the cfe-commits
mailing list