forked from OSchip/llvm-project
				
			
		
			
				
	
	
		
			79 lines
		
	
	
		
			2.2 KiB
		
	
	
	
		
			C++
		
	
	
	
			
		
		
	
	
			79 lines
		
	
	
		
			2.2 KiB
		
	
	
	
		
			C++
		
	
	
	
//===--- TransUnusedInitDelegate.cpp - Transformations to ARC mode --------===//
 | 
						|
//
 | 
						|
//                     The LLVM Compiler Infrastructure
 | 
						|
//
 | 
						|
// This file is distributed under the University of Illinois Open Source
 | 
						|
// License. See LICENSE.TXT for details.
 | 
						|
//
 | 
						|
//===----------------------------------------------------------------------===//
 | 
						|
// Transformations:
 | 
						|
//===----------------------------------------------------------------------===//
 | 
						|
//
 | 
						|
// rewriteUnusedInitDelegate:
 | 
						|
//
 | 
						|
// Rewrites an unused result of calling a delegate initialization, to assigning
 | 
						|
// the result to self.
 | 
						|
// e.g
 | 
						|
//  [self init];
 | 
						|
// ---->
 | 
						|
//  self = [self init];
 | 
						|
//
 | 
						|
//===----------------------------------------------------------------------===//
 | 
						|
 | 
						|
#include "Transforms.h"
 | 
						|
#include "Internals.h"
 | 
						|
#include "clang/AST/ASTContext.h"
 | 
						|
#include "clang/Sema/SemaDiagnostic.h"
 | 
						|
 | 
						|
using namespace clang;
 | 
						|
using namespace arcmt;
 | 
						|
using namespace trans;
 | 
						|
 | 
						|
namespace {
 | 
						|
 | 
						|
class UnusedInitRewriter : public RecursiveASTVisitor<UnusedInitRewriter> {
 | 
						|
  Stmt *Body;
 | 
						|
  MigrationPass &Pass;
 | 
						|
 | 
						|
  ExprSet Removables;
 | 
						|
 | 
						|
public:
 | 
						|
  UnusedInitRewriter(MigrationPass &pass)
 | 
						|
    : Body(nullptr), Pass(pass) { }
 | 
						|
 | 
						|
  void transformBody(Stmt *body, Decl *ParentD) {
 | 
						|
    Body = body;
 | 
						|
    collectRemovables(body, Removables);
 | 
						|
    TraverseStmt(body);
 | 
						|
  }
 | 
						|
 | 
						|
  bool VisitObjCMessageExpr(ObjCMessageExpr *ME) {
 | 
						|
    if (ME->isDelegateInitCall() &&
 | 
						|
        isRemovable(ME) &&
 | 
						|
        Pass.TA.hasDiagnostic(diag::err_arc_unused_init_message,
 | 
						|
                              ME->getExprLoc())) {
 | 
						|
      Transaction Trans(Pass.TA);
 | 
						|
      Pass.TA.clearDiagnostic(diag::err_arc_unused_init_message,
 | 
						|
                              ME->getExprLoc());
 | 
						|
      SourceRange ExprRange = ME->getSourceRange();
 | 
						|
      Pass.TA.insert(ExprRange.getBegin(), "if (!(self = ");
 | 
						|
      std::string retStr = ")) return ";
 | 
						|
      retStr += getNilString(Pass);
 | 
						|
      Pass.TA.insertAfterToken(ExprRange.getEnd(), retStr);
 | 
						|
    }
 | 
						|
    return true;
 | 
						|
  }
 | 
						|
 | 
						|
private:
 | 
						|
  bool isRemovable(Expr *E) const {
 | 
						|
    return Removables.count(E);
 | 
						|
  }
 | 
						|
};
 | 
						|
 | 
						|
} // anonymous namespace
 | 
						|
 | 
						|
void trans::rewriteUnusedInitDelegate(MigrationPass &pass) {
 | 
						|
  BodyTransform<UnusedInitRewriter> trans(pass);
 | 
						|
  trans.TraverseDecl(pass.Ctx.getTranslationUnitDecl());
 | 
						|
}
 |