[cfe-commits] r149027 - in /cfe/trunk: include/clang/Basic/Diagnostic.h include/clang/Driver/CC1Options.td include/clang/Frontend/FrontendOptions.h include/clang/Rewrite/FixItRewriter.h include/clang/Rewrite/FrontendActions.h lib/Frontend/CompilerInvocation.cpp lib/FrontendTool/ExecuteCompilerInvocation.cpp lib/Rewrite/FixItRewriter.cpp lib/Rewrite/FrontendActions.cpp test/FixIt/fixit-recompile.c
Argyrios Kyrtzidis
akyrtzi at gmail.com
Wed Jan 25 18:40:49 PST 2012
Author: akirtzidis
Date: Wed Jan 25 20:40:48 2012
New Revision: 149027
URL: http://llvm.org/viewvc/llvm-project?rev=149027&view=rev
Log:
Introduce 3 new fixit options:
-fixit-recompile
applies fixits and recompiles the result
-fixit-to-temporary
applies fixits to temporary files
-fix-only-warnings">,
applies fixits for warnings only, not errors
Combining "-fixit-recompile -fixit-to-temporary" allows testing the result of fixits
without touching the original sources.
Added:
cfe/trunk/test/FixIt/fixit-recompile.c
Modified:
cfe/trunk/include/clang/Basic/Diagnostic.h
cfe/trunk/include/clang/Driver/CC1Options.td
cfe/trunk/include/clang/Frontend/FrontendOptions.h
cfe/trunk/include/clang/Rewrite/FixItRewriter.h
cfe/trunk/include/clang/Rewrite/FrontendActions.h
cfe/trunk/lib/Frontend/CompilerInvocation.cpp
cfe/trunk/lib/FrontendTool/ExecuteCompilerInvocation.cpp
cfe/trunk/lib/Rewrite/FixItRewriter.cpp
cfe/trunk/lib/Rewrite/FrontendActions.cpp
Modified: cfe/trunk/include/clang/Basic/Diagnostic.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/Diagnostic.h?rev=149027&r1=149026&r2=149027&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/Diagnostic.h (original)
+++ cfe/trunk/include/clang/Basic/Diagnostic.h Wed Jan 25 20:40:48 2012
@@ -1070,6 +1070,7 @@
unsigned getNumErrors() const { return NumErrors; }
unsigned getNumWarnings() const { return NumWarnings; }
+ virtual void clear() { NumWarnings = NumErrors = 0; }
virtual ~DiagnosticConsumer();
Modified: cfe/trunk/include/clang/Driver/CC1Options.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Driver/CC1Options.td?rev=149027&r1=149026&r2=149027&view=diff
==============================================================================
--- cfe/trunk/include/clang/Driver/CC1Options.td (original)
+++ cfe/trunk/include/clang/Driver/CC1Options.td Wed Jan 25 20:40:48 2012
@@ -453,6 +453,12 @@
HelpText<"Dump record layout information">;
def fix_what_you_can : Flag<"-fix-what-you-can">,
HelpText<"Apply fix-it advice even in the presence of unfixable errors">;
+def fix_only_warnings : Flag<"-fix-only-warnings">,
+ HelpText<"Apply fix-it advice only for warnings, not errors">;
+def fixit_recompile : Flag<"-fixit-recompile">,
+ HelpText<"Apply fix-it changes and recompile">;
+def fixit_to_temp : Flag<"-fixit-to-temporary">,
+ HelpText<"Apply fix-it changes to temporary files">;
// Generic forwarding to LLVM options. This should only be used for debugging
// and experimental features.
Modified: cfe/trunk/include/clang/Frontend/FrontendOptions.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Frontend/FrontendOptions.h?rev=149027&r1=149026&r2=149027&view=diff
==============================================================================
--- cfe/trunk/include/clang/Frontend/FrontendOptions.h (original)
+++ cfe/trunk/include/clang/Frontend/FrontendOptions.h Wed Jan 25 20:40:48 2012
@@ -102,6 +102,9 @@
unsigned ShowVersion : 1; ///< Show the -version text.
unsigned FixWhatYouCan : 1; ///< Apply fixes even if there are
/// unfixable errors.
+ unsigned FixOnlyWarnings : 1; ///< Apply fixes only for warnings.
+ unsigned FixAndRecompile : 1; ///< Apply fixes and recompile.
+ unsigned FixToTemporaries : 1; ///< Apply fixes to temporary files.
unsigned ARCMTMigrateEmitARCErrors : 1; /// Emit ARC errors even if the
/// migrator can fix them
Modified: cfe/trunk/include/clang/Rewrite/FixItRewriter.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Rewrite/FixItRewriter.h?rev=149027&r1=149026&r2=149027&view=diff
==============================================================================
--- cfe/trunk/include/clang/Rewrite/FixItRewriter.h (original)
+++ cfe/trunk/include/clang/Rewrite/FixItRewriter.h Wed Jan 25 20:40:48 2012
@@ -26,6 +26,9 @@
class FixItOptions {
public:
+ FixItOptions() : FixWhatYouCan(false),
+ FixOnlyWarnings(false), Silent(false) { }
+
virtual ~FixItOptions();
/// \brief This file is about to be rewritten. Return the name of the file
@@ -34,6 +37,14 @@
/// \brief Whether to abort fixing a file when not all errors could be fixed.
bool FixWhatYouCan;
+
+ /// \brief Whether to only fix warnings and not errors.
+ bool FixOnlyWarnings;
+
+ /// \brief If true, only pass the diagnostic to the actual diagnostic consumer
+ /// if it is an error or a fixit was applied as part of the diagnostic.
+ /// It basically silences warnings without accompanying fixits.
+ bool Silent;
};
class FixItRewriter : public DiagnosticConsumer {
@@ -47,6 +58,7 @@
/// \brief The diagnostic client that performs the actual formatting
/// of error messages.
DiagnosticConsumer *Client;
+ bool OwnsClient;
/// \brief Turn an input path into an output path. NULL implies overwriting
/// the original.
@@ -55,6 +67,9 @@
/// \brief The number of rewriter failures.
unsigned NumFailures;
+ /// \brief Whether the previous diagnostic was not passed to the consumer.
+ bool PrevDiagSilenced;
+
public:
typedef Rewriter::buffer_iterator iterator;
@@ -82,7 +97,8 @@
/// \brief Write the modified source files.
///
/// \returns true if there was an error, false otherwise.
- bool WriteFixedFiles();
+ bool WriteFixedFiles(
+ std::vector<std::pair<std::string, std::string> > *RewrittenFiles = 0);
/// IncludeInDiagnosticCounts - This method (whose default implementation
/// returns true) indicates whether the diagnostics handled by this
Modified: cfe/trunk/include/clang/Rewrite/FrontendActions.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Rewrite/FrontendActions.h?rev=149027&r1=149026&r2=149027&view=diff
==============================================================================
--- cfe/trunk/include/clang/Rewrite/FrontendActions.h (original)
+++ cfe/trunk/include/clang/Rewrite/FrontendActions.h Wed Jan 25 20:40:48 2012
@@ -46,6 +46,18 @@
~FixItAction();
};
+/// \brief Emits changes to temporary files and uses them for the original
+/// frontend action.
+class FixItRecompile : public WrapperFrontendAction {
+ FrontendAction *WrappedAction;
+public:
+ FixItRecompile(FrontendAction *WrappedAction)
+ : WrapperFrontendAction(WrappedAction), WrappedAction(WrappedAction) {}
+
+protected:
+ virtual bool BeginInvocation(CompilerInstance &CI);
+};
+
class RewriteObjCAction : public ASTFrontendAction {
protected:
virtual ASTConsumer *CreateASTConsumer(CompilerInstance &CI,
Modified: cfe/trunk/lib/Frontend/CompilerInvocation.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/CompilerInvocation.cpp?rev=149027&r1=149026&r2=149027&view=diff
==============================================================================
--- cfe/trunk/lib/Frontend/CompilerInvocation.cpp (original)
+++ cfe/trunk/lib/Frontend/CompilerInvocation.cpp Wed Jan 25 20:40:48 2012
@@ -466,6 +466,12 @@
Res.push_back("-version");
if (Opts.FixWhatYouCan)
Res.push_back("-fix-what-you-can");
+ if (Opts.FixOnlyWarnings)
+ Res.push_back("-fix-only-warnings");
+ if (Opts.FixAndRecompile)
+ Res.push_back("-fixit-recompile");
+ if (Opts.FixToTemporaries)
+ Res.push_back("-fixit-to-temporary");
switch (Opts.ARCMTAction) {
case FrontendOptions::ARCMT_None:
break;
@@ -1401,6 +1407,9 @@
Opts.ASTMergeFiles = Args.getAllArgValues(OPT_ast_merge);
Opts.LLVMArgs = Args.getAllArgValues(OPT_mllvm);
Opts.FixWhatYouCan = Args.hasArg(OPT_fix_what_you_can);
+ Opts.FixOnlyWarnings = Args.hasArg(OPT_fix_only_warnings);
+ Opts.FixAndRecompile = Args.hasArg(OPT_fixit_recompile);
+ Opts.FixToTemporaries = Args.hasArg(OPT_fixit_to_temp);
Opts.ARCMTAction = FrontendOptions::ARCMT_None;
if (const Arg *A = Args.getLastArg(OPT_arcmt_check,
Modified: cfe/trunk/lib/FrontendTool/ExecuteCompilerInvocation.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/FrontendTool/ExecuteCompilerInvocation.cpp?rev=149027&r1=149026&r2=149027&view=diff
==============================================================================
--- cfe/trunk/lib/FrontendTool/ExecuteCompilerInvocation.cpp (original)
+++ cfe/trunk/lib/FrontendTool/ExecuteCompilerInvocation.cpp Wed Jan 25 20:40:48 2012
@@ -87,6 +87,10 @@
if (!Act)
return 0;
+ if (CI.getFrontendOpts().FixAndRecompile) {
+ Act = new FixItRecompile(Act);
+ }
+
// Potentially wrap the base FE action in an ARC Migrate Tool action.
switch (CI.getFrontendOpts().ARCMTAction) {
case FrontendOptions::ARCMT_None:
Modified: cfe/trunk/lib/Rewrite/FixItRewriter.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Rewrite/FixItRewriter.cpp?rev=149027&r1=149026&r2=149027&view=diff
==============================================================================
--- cfe/trunk/lib/Rewrite/FixItRewriter.cpp (original)
+++ cfe/trunk/lib/Rewrite/FixItRewriter.cpp Wed Jan 25 20:40:48 2012
@@ -31,14 +31,16 @@
: Diags(Diags),
Rewrite(SourceMgr, LangOpts),
FixItOpts(FixItOpts),
- NumFailures(0) {
+ NumFailures(0),
+ PrevDiagSilenced(false) {
+ OwnsClient = Diags.ownsClient();
Client = Diags.takeClient();
Diags.setClient(this);
}
FixItRewriter::~FixItRewriter() {
Diags.takeClient();
- Diags.setClient(Client);
+ Diags.setClient(Client, OwnsClient);
}
bool FixItRewriter::WriteFixedFile(FileID ID, raw_ostream &OS) {
@@ -49,7 +51,8 @@
return false;
}
-bool FixItRewriter::WriteFixedFiles() {
+bool FixItRewriter::WriteFixedFiles(
+ std::vector<std::pair<std::string, std::string> > *RewrittenFiles) {
if (NumFailures > 0 && !FixItOpts->FixWhatYouCan) {
Diag(FullSourceLoc(), diag::warn_fixit_no_changes);
return true;
@@ -69,6 +72,9 @@
RewriteBuffer &RewriteBuf = I->second;
RewriteBuf.write(OS);
OS.flush();
+
+ if (RewrittenFiles)
+ RewrittenFiles->push_back(std::make_pair(Entry->getName(), Filename));
}
return false;
@@ -83,11 +89,24 @@
// Default implementation (Warnings/errors count).
DiagnosticConsumer::HandleDiagnostic(DiagLevel, Info);
- Client->HandleDiagnostic(DiagLevel, Info);
+ if (!FixItOpts->Silent ||
+ DiagLevel >= DiagnosticsEngine::Error ||
+ (DiagLevel == DiagnosticsEngine::Note && !PrevDiagSilenced) ||
+ (DiagLevel > DiagnosticsEngine::Note && Info.getNumFixItHints())) {
+ Client->HandleDiagnostic(DiagLevel, Info);
+ PrevDiagSilenced = false;
+ } else {
+ PrevDiagSilenced = true;
+ }
// Skip over any diagnostics that are ignored or notes.
if (DiagLevel <= DiagnosticsEngine::Note)
return;
+ // Skip over errors if we are only fixing warnings.
+ if (DiagLevel >= DiagnosticsEngine::Error && FixItOpts->FixOnlyWarnings) {
+ ++NumFailures;
+ return;
+ }
// Make sure that we can perform all of the modifications we
// in this diagnostic.
@@ -107,8 +126,7 @@
Diag(Info.getLocation(), diag::note_fixit_in_macro);
// If this was an error, refuse to perform any rewriting.
- if (DiagLevel == DiagnosticsEngine::Error ||
- DiagLevel == DiagnosticsEngine::Fatal) {
+ if (DiagLevel >= DiagnosticsEngine::Error) {
if (++NumFailures == 1)
Diag(Info.getLocation(), diag::note_fixit_unfixed_error);
}
Modified: cfe/trunk/lib/Rewrite/FrontendActions.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Rewrite/FrontendActions.cpp?rev=149027&r1=149026&r2=149027&view=diff
==============================================================================
--- cfe/trunk/lib/Rewrite/FrontendActions.cpp (original)
+++ cfe/trunk/lib/Rewrite/FrontendActions.cpp Wed Jan 25 20:40:48 2012
@@ -12,6 +12,7 @@
#include "clang/Lex/Preprocessor.h"
#include "clang/Parse/Parser.h"
#include "clang/Basic/FileManager.h"
+#include "clang/Frontend/FrontendActions.h"
#include "clang/Frontend/CompilerInstance.h"
#include "clang/Frontend/FrontendDiagnostic.h"
#include "clang/Frontend/Utils.h"
@@ -21,6 +22,7 @@
#include "llvm/ADT/OwningPtr.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Support/Path.h"
+#include "llvm/Support/FileSystem.h"
using namespace clang;
//===----------------------------------------------------------------------===//
@@ -64,6 +66,22 @@
return Path.str();
}
};
+
+class FixItRewriteToTemp : public FixItOptions {
+public:
+ std::string RewriteFilename(const std::string &Filename) {
+ llvm::SmallString<128> Path;
+ Path = llvm::sys::path::filename(Filename);
+ Path += "-%%%%%%%%";
+ Path += llvm::sys::path::extension(Filename);
+ int fd;
+ llvm::SmallString<128> NewPath;
+ if (llvm::sys::fs::unique_file(Path.str(), fd, NewPath)
+ == llvm::errc::success)
+ ::close(fd);
+ return NewPath.str();
+ }
+};
} // end anonymous namespace
bool FixItAction::BeginSourceFileAction(CompilerInstance &CI,
@@ -86,6 +104,45 @@
Rewriter->WriteFixedFiles();
}
+bool FixItRecompile::BeginInvocation(CompilerInstance &CI) {
+
+ std::vector<std::pair<std::string, std::string> > RewrittenFiles;
+ bool err = false;
+ {
+ const FrontendOptions &FEOpts = CI.getFrontendOpts();
+ llvm::OwningPtr<FrontendAction> FixAction(new SyntaxOnlyAction());
+ FixAction->BeginSourceFile(CI, FEOpts.Inputs[0]);
+
+ llvm::OwningPtr<FixItOptions> FixItOpts;
+ if (FEOpts.FixToTemporaries)
+ FixItOpts.reset(new FixItRewriteToTemp());
+ else
+ FixItOpts.reset(new FixItRewriteInPlace());
+ FixItOpts->Silent = true;
+ FixItOpts->FixWhatYouCan = FEOpts.FixWhatYouCan;
+ FixItOpts->FixOnlyWarnings = FEOpts.FixOnlyWarnings;
+ FixItRewriter Rewriter(CI.getDiagnostics(), CI.getSourceManager(),
+ CI.getLangOpts(), FixItOpts.get());
+ FixAction->Execute();
+
+ err = Rewriter.WriteFixedFiles(&RewrittenFiles);
+
+ FixAction->EndSourceFile();
+ CI.setSourceManager(0);
+ CI.setFileManager(0);
+ }
+ if (err)
+ return false;
+ CI.getDiagnosticClient().clear();
+
+ PreprocessorOptions &PPOpts = CI.getPreprocessorOpts();
+ PPOpts.RemappedFiles.insert(PPOpts.RemappedFiles.end(),
+ RewrittenFiles.begin(), RewrittenFiles.end());
+ PPOpts.RemappedFilesKeepOriginalName = false;
+
+ return true;
+}
+
//===----------------------------------------------------------------------===//
// Preprocessor Actions
//===----------------------------------------------------------------------===//
Added: cfe/trunk/test/FixIt/fixit-recompile.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/FixIt/fixit-recompile.c?rev=149027&view=auto
==============================================================================
--- cfe/trunk/test/FixIt/fixit-recompile.c (added)
+++ cfe/trunk/test/FixIt/fixit-recompile.c Wed Jan 25 20:40:48 2012
@@ -0,0 +1,6 @@
+// RUN: %clang_cc1 -Werror -pedantic %s -fixit-recompile -fixit-to-temporary -E -o - | FileCheck %s
+// RUN: not %clang_cc1 -Werror -pedantic %s -fixit-recompile -fixit-to-temporary -fix-only-warnings
+
+_Complex cd;
+
+// CHECK: _Complex double cd;
More information about the cfe-commits
mailing list