arc migrator: Provide infrastructure to add options

specific to migrator. Use its first option to
warn migrating from GC to arc when 
NSAllocateCollectable/NSReallocateCollectable is used.
// rdar://10532541

llvm-svn: 148887
This commit is contained in:
Fariborz Jahanian 2012-01-25 00:20:29 +00:00
parent c454afedff
commit aa7b9aa10d
9 changed files with 97 additions and 4 deletions

View File

@ -100,6 +100,12 @@ def analyzer_disable_checker_EQ : Joined<"-analyzer-disable-checker=">,
def analyzer_checker_help : Flag<"-analyzer-checker-help">,
HelpText<"Display the list of analyzer checkers that are available">;
//===----------------------------------------------------------------------===//
// Migrator Options
//===----------------------------------------------------------------------===//
def migrator_no_nsalloc_error : Flag<"-no-ns-alloc-error">,
HelpText<"Do not error on use of NSAllocateCollectable/NSReallocateCollectable">;
//===----------------------------------------------------------------------===//
// CodeGen Options
//===----------------------------------------------------------------------===//

View File

@ -14,6 +14,7 @@
#include "clang/Basic/TargetOptions.h"
#include "clang/Basic/FileSystemOptions.h"
#include "clang/Frontend/AnalyzerOptions.h"
#include "clang/Frontend/MigratorOptions.h"
#include "clang/Frontend/CodeGenOptions.h"
#include "clang/Frontend/DependencyOutputOptions.h"
#include "clang/Frontend/DiagnosticOptions.h"
@ -56,6 +57,8 @@ class CompilerInvocation : public CompilerInvocationBase {
/// Options controlling the static analyzer.
AnalyzerOptions AnalyzerOpts;
MigratorOptions MigratorOpts;
/// Options controlling IRgen and the backend.
CodeGenOptions CodeGenOpts;
@ -147,6 +150,11 @@ public:
return AnalyzerOpts;
}
MigratorOptions &getMigratorOpts() { return MigratorOpts; }
const MigratorOptions &getMigratorOpts() const {
return MigratorOpts;
}
CodeGenOptions &getCodeGenOpts() { return CodeGenOpts; }
const CodeGenOptions &getCodeGenOpts() const {
return CodeGenOpts;

View File

@ -0,0 +1,29 @@
//===--- MigratorOptions.h - MigratorOptions Options ------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This header contains the structures necessary for a front-end to specify
// various migration analysis.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_CLANG_FRONTEND_MIGRATOROPTIONS
#define LLVM_CLANG_FRONTEND_MIGRATOROPTIONS
namespace clang {
class MigratorOptions {
public:
unsigned NoNSAllocReallocError : 1;
MigratorOptions() {
NoNSAllocReallocError = 0;
}
};
}
#endif

View File

@ -229,6 +229,7 @@ bool arcmt::checkForManualIssues(CompilerInvocation &origCI,
return false;
LangOptions::GCMode OrigGCMode = origCI.getLangOpts()->getGC();
bool NoNSAllocReallocError = origCI.getMigratorOpts().NoNSAllocReallocError;
std::vector<TransformFn> transforms = arcmt::getAllTransformations(OrigGCMode);
assert(!transforms.empty());
@ -292,6 +293,7 @@ bool arcmt::checkForManualIssues(CompilerInvocation &origCI,
TransformActions testAct(*Diags, capturedDiags, Ctx, Unit->getPreprocessor());
MigrationPass pass(Ctx, OrigGCMode, Unit->getSema(), testAct, ARCMTMacroLocs);
pass.setNSAllocReallocError(NoNSAllocReallocError);
for (unsigned i=0, e = transforms.size(); i != e; ++i)
transforms[i](pass);

View File

@ -94,6 +94,8 @@ public:
void reportError(StringRef error, SourceLocation loc,
SourceRange range = SourceRange());
void reportWarning(StringRef warning, SourceLocation loc,
SourceRange range = SourceRange());
void reportNote(StringRef note, SourceLocation loc,
SourceRange range = SourceRange());
@ -138,6 +140,7 @@ class MigrationPass {
public:
ASTContext &Ctx;
LangOptions::GCMode OrigGCMode;
MigratorOptions MigOptions;
Sema &SemaRef;
TransformActions &TA;
std::vector<SourceLocation> &ARCMTMacroLocs;
@ -145,10 +148,13 @@ public:
MigrationPass(ASTContext &Ctx, LangOptions::GCMode OrigGCMode,
Sema &sema, TransformActions &TA,
std::vector<SourceLocation> &ARCMTMacroLocs)
: Ctx(Ctx), OrigGCMode(OrigGCMode), SemaRef(sema), TA(TA),
: Ctx(Ctx), OrigGCMode(OrigGCMode), MigOptions(),
SemaRef(sema), TA(TA),
ARCMTMacroLocs(ARCMTMacroLocs) { }
bool isGCMigration() const { return OrigGCMode != LangOptions::NonGC; }
bool noNSAllocReallocError() const { return MigOptions.NoNSAllocReallocError; }
void setNSAllocReallocError(bool val) { MigOptions.NoNSAllocReallocError = val; }
};
static inline StringRef getARCMTMacroName() {

View File

@ -38,9 +38,14 @@ public:
TransformActions &TA = MigrateCtx.Pass.TA;
if (MigrateCtx.isGCOwnedNonObjC(E->getType())) {
TA.reportError("call returns pointer to GC managed memory; "
"it will become unmanaged in ARC",
E->getLocStart(), E->getSourceRange());
if (MigrateCtx.Pass.noNSAllocReallocError())
TA.reportWarning("call returns pointer to GC managed memory; "
"it will become unmanaged in ARC",
E->getLocStart(), E->getSourceRange());
else
TA.reportError("call returns pointer to GC managed memory; "
"it will become unmanaged in ARC",
E->getLocStart(), E->getSourceRange());
return true;
}

View File

@ -692,6 +692,25 @@ void TransformActions::reportError(StringRef error, SourceLocation loc,
ReportedErrors = true;
}
void TransformActions::reportWarning(StringRef warning, SourceLocation loc,
SourceRange range) {
assert(!static_cast<TransformActionsImpl*>(Impl)->isInTransaction() &&
"Warning should be emitted out of a transaction");
SourceManager &SM = static_cast<TransformActionsImpl*>(Impl)->
getASTContext().getSourceManager();
if (SM.isInSystemHeader(SM.getExpansionLoc(loc)))
return;
// FIXME: Use a custom category name to distinguish rewriter errors.
std::string rewriterWarn = "[rewriter] ";
rewriterWarn += warning;
unsigned diagID
= Diags.getDiagnosticIDs()->getCustomDiagID(DiagnosticIDs::Warning,
rewriterWarn);
Diags.Report(loc, diagID) << range;
}
void TransformActions::reportNote(StringRef note, SourceLocation loc,
SourceRange range) {
assert(!static_cast<TransformActionsImpl*>(Impl)->isInTransaction() &&

View File

@ -1053,6 +1053,11 @@ static bool ParseAnalyzerArgs(AnalyzerOptions &Opts, ArgList &Args,
return Success;
}
static bool ParseMigratorArgs(MigratorOptions &Opts, ArgList &Args) {
Opts.NoNSAllocReallocError = Args.hasArg(OPT_migrator_no_nsalloc_error);
return true;
}
static bool ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args, InputKind IK,
DiagnosticsEngine &Diags) {
using namespace cc1options;
@ -2051,6 +2056,7 @@ bool CompilerInvocation::CreateFromArgs(CompilerInvocation &Res,
}
Success = ParseAnalyzerArgs(Res.getAnalyzerOpts(), *Args, Diags) && Success;
Success = ParseMigratorArgs(Res.getMigratorOpts(), *Args) && Success;
ParseDependencyOutputArgs(Res.getDependencyOutputOpts(), *Args);
Success = ParseDiagnosticArgs(Res.getDiagnosticOpts(), *Args, Diags)
&& Success;

View File

@ -0,0 +1,12 @@
// RUN: %clang_cc1 -arcmt-check -verify -no-ns-alloc-error -triple x86_64-apple-darwin10 -fobjc-gc-only %s
// RUN: %clang_cc1 -arcmt-check -verify -no-ns-alloc-error -triple x86_64-apple-darwin10 -fobjc-gc-only -x objective-c++ %s
// DISABLE: mingw32
// rdar://10532541
// XFAIL: *
typedef unsigned NSUInteger;
void *__strong NSAllocateCollectable(NSUInteger size, NSUInteger options);
void test1() {
NSAllocateCollectable(100, 0); // expected-warning {{call returns pointer to GC managed memory; it will become unmanaged in ARC}}
}