//===--- 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 *