forked from OSchip/llvm-project
				
			
		
			
				
	
	
		
			78 lines
		
	
	
		
			2.5 KiB
		
	
	
	
		
			C++
		
	
	
	
			
		
		
	
	
			78 lines
		
	
	
		
			2.5 KiB
		
	
	
	
		
			C++
		
	
	
	
//===--- TransGCCalls.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.
 | 
						|
//
 | 
						|
//===----------------------------------------------------------------------===//
 | 
						|
 | 
						|
#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 GCCollectableCallsChecker :
 | 
						|
                         public RecursiveASTVisitor<GCCollectableCallsChecker> {
 | 
						|
  MigrationContext &MigrateCtx;
 | 
						|
  IdentifierInfo *NSMakeCollectableII;
 | 
						|
  IdentifierInfo *CFMakeCollectableII;
 | 
						|
 | 
						|
public:
 | 
						|
  GCCollectableCallsChecker(MigrationContext &ctx)
 | 
						|
    : MigrateCtx(ctx) {
 | 
						|
    IdentifierTable &Ids = MigrateCtx.Pass.Ctx.Idents;
 | 
						|
    NSMakeCollectableII = &Ids.get("NSMakeCollectable");
 | 
						|
    CFMakeCollectableII = &Ids.get("CFMakeCollectable");
 | 
						|
  }
 | 
						|
 | 
						|
  bool shouldWalkTypesOfTypeLocs() const { return false; }
 | 
						|
 | 
						|
  bool VisitCallExpr(CallExpr *E) {
 | 
						|
    TransformActions &TA = MigrateCtx.Pass.TA;
 | 
						|
 | 
						|
    if (MigrateCtx.isGCOwnedNonObjC(E->getType())) {
 | 
						|
      TA.report(E->getLocStart(), diag::warn_arcmt_nsalloc_realloc,
 | 
						|
                E->getSourceRange());
 | 
						|
      return true;
 | 
						|
    }
 | 
						|
 | 
						|
    Expr *CEE = E->getCallee()->IgnoreParenImpCasts();
 | 
						|
    if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(CEE)) {
 | 
						|
      if (FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>(DRE->getDecl())) {
 | 
						|
        if (!FD->getDeclContext()->getRedeclContext()->isFileContext())
 | 
						|
          return true;
 | 
						|
 | 
						|
        if (FD->getIdentifier() == NSMakeCollectableII) {
 | 
						|
          Transaction Trans(TA);
 | 
						|
          TA.clearDiagnostic(diag::err_unavailable,
 | 
						|
                             diag::err_unavailable_message,
 | 
						|
                             diag::err_ovl_deleted_call, // ObjC++
 | 
						|
                             DRE->getSourceRange());
 | 
						|
          TA.replace(DRE->getSourceRange(), "CFBridgingRelease");
 | 
						|
 | 
						|
        } else if (FD->getIdentifier() == CFMakeCollectableII) {
 | 
						|
          TA.reportError("CFMakeCollectable will leak the object that it "
 | 
						|
                         "receives in ARC", DRE->getLocation(),
 | 
						|
                         DRE->getSourceRange());
 | 
						|
        }
 | 
						|
      }
 | 
						|
    }
 | 
						|
 | 
						|
    return true;
 | 
						|
  }
 | 
						|
};
 | 
						|
 | 
						|
} // anonymous namespace
 | 
						|
 | 
						|
void GCCollectableCallsTraverser::traverseBody(BodyContext &BodyCtx) {
 | 
						|
  GCCollectableCallsChecker(BodyCtx.getMigrationContext())
 | 
						|
                                            .TraverseStmt(BodyCtx.getTopStmt());
 | 
						|
}
 |