diff options
Diffstat (limited to 'lib/Frontend')
-rw-r--r-- | lib/Frontend/CompilerInvocation.cpp | 23 | ||||
-rw-r--r-- | lib/Frontend/FixItRewriter.cpp | 64 | ||||
-rw-r--r-- | lib/Frontend/FrontendActions.cpp | 90 |
3 files changed, 40 insertions, 137 deletions
diff --git a/lib/Frontend/CompilerInvocation.cpp b/lib/Frontend/CompilerInvocation.cpp index 3386eff5ba..db937bc4c7 100644 --- a/lib/Frontend/CompilerInvocation.cpp +++ b/lib/Frontend/CompilerInvocation.cpp @@ -361,12 +361,6 @@ static void FrontendOptsToArgs(const FrontendOptions &Opts, Res.push_back("-cxx-inheritance-view"); Res.push_back(Opts.ViewClassInheritance); } - for (unsigned i = 0, e = Opts.FixItLocations.size(); i != e; ++i) { - Res.push_back("-fixit-at"); - Res.push_back(Opts.FixItLocations[i].FileName + ":" + - llvm::utostr(Opts.FixItLocations[i].Line) + ":" + - llvm::utostr(Opts.FixItLocations[i].Column)); - } if (!Opts.CodeCompletionAt.FileName.empty()) { Res.push_back("-code-completion-at"); Res.push_back(Opts.CodeCompletionAt.FileName + ":" + @@ -910,6 +904,9 @@ ParseFrontendArgs(FrontendOptions &Opts, ArgList &Args, Diagnostic &Diags) { Opts.ProgramAction = frontend::EmitLLVMOnly; break; case OPT_emit_obj: Opts.ProgramAction = frontend::EmitObj; break; + case OPT_fixit_EQ: + Opts.FixItSuffix = A->getValue(Args); + // fall-through! case OPT_fixit: Opts.ProgramAction = frontend::FixIt; break; case OPT_emit_pch: @@ -956,20 +953,6 @@ ParseFrontendArgs(FrontendOptions &Opts, ArgList &Args, Diagnostic &Diags) { !Args.hasArg(OPT_no_code_completion_debug_printer); Opts.DisableFree = Args.hasArg(OPT_disable_free); - Opts.FixItLocations.clear(); - for (arg_iterator it = Args.filtered_begin(OPT_fixit_at), - ie = Args.filtered_end(); it != ie; ++it) { - const char *Loc = it->getValue(Args); - ParsedSourceLocation PSL = ParsedSourceLocation::FromString(Loc); - - if (PSL.FileName.empty()) { - Diags.Report(diag::err_drv_invalid_value) << it->getAsString(Args) << Loc; - continue; - } - - Opts.FixItLocations.push_back(PSL); - } - Opts.OutputFile = getLastArgValue(Args, OPT_o); Opts.Plugins = getAllArgValues(Args, OPT_load); Opts.RelocatablePCH = Args.hasArg(OPT_relocatable_pch); diff --git a/lib/Frontend/FixItRewriter.cpp b/lib/Frontend/FixItRewriter.cpp index 7aff92340e..cb2b44a027 100644 --- a/lib/Frontend/FixItRewriter.cpp +++ b/lib/Frontend/FixItRewriter.cpp @@ -26,8 +26,12 @@ using namespace clang; FixItRewriter::FixItRewriter(Diagnostic &Diags, SourceManager &SourceMgr, - const LangOptions &LangOpts) - : Diags(Diags), Rewrite(SourceMgr, LangOpts), NumFailures(0) { + const LangOptions &LangOpts, + FixItPathRewriter *PathRewriter) + : Diags(Diags), + Rewrite(SourceMgr, LangOpts), + PathRewriter(PathRewriter), + NumFailures(0) { Client = Diags.getClient(); Diags.setClient(this); } @@ -52,15 +56,15 @@ bool FixItRewriter::WriteFixedFiles() { for (iterator I = buffer_begin(), E = buffer_end(); I != E; ++I) { const FileEntry *Entry = Rewrite.getSourceMgr().getFileEntryForID(I->first); - llvm::sys::Path Path(Entry->getName()); - std::string Suffix = Path.getSuffix(); - Path.eraseSuffix(); - Path.appendSuffix("fixit." + Suffix); + std::string Filename = Entry->getName(); + if (PathRewriter) + Filename = PathRewriter->RewriteFilename(Filename); std::string Err; - llvm::raw_fd_ostream OS(Path.c_str(), Err, llvm::raw_fd_ostream::F_Binary); + llvm::raw_fd_ostream OS(Filename.c_str(), Err, + llvm::raw_fd_ostream::F_Binary); if (!Err.empty()) { Diags.Report(clang::diag::err_fe_unable_to_open_output) - << Path.c_str() << Err; + << Filename << Err; continue; } RewriteBuffer &RewriteBuf = I->second; @@ -79,48 +83,10 @@ void FixItRewriter::HandleDiagnostic(Diagnostic::Level DiagLevel, const DiagnosticInfo &Info) { Client->HandleDiagnostic(DiagLevel, Info); - // Skip over any diagnostics that are ignored. - if (DiagLevel == Diagnostic::Ignored) + // Skip over any diagnostics that are ignored or notes. + if (DiagLevel <= Diagnostic::Note) return; - const SourceManager &SM = Rewrite.getSourceMgr(); - if (!FixItLocations.empty()) { - // The user has specified the locations where we should perform - // the various fix-it modifications. - - // If this diagnostic does not have any code modifications, - // completely ignore it, even if it's an error: fix-it locations - // are meant to perform specific fix-ups even in the presence of - // other errors. - if (Info.getNumFixItHints() == 0) - return; - - // See if the location of the error is one that matches what the - // user requested. - bool AcceptableLocation = false; - const FileEntry *File = SM.getFileEntryForID( - Info.getLocation().getFileID()); - unsigned Line = Info.getLocation().getSpellingLineNumber(); - unsigned Column = Info.getLocation().getSpellingColumnNumber(); - for (llvm::SmallVector<RequestedSourceLocation, 4>::iterator - Loc = FixItLocations.begin(), LocEnd = FixItLocations.end(); - Loc != LocEnd; ++Loc) { - if (Loc->File == File && - ((Loc->Line == 0 && Loc->Column == 0 && - DiagLevel > Diagnostic::Note) || - (Loc->Line == Line && Loc->Column == Column))) { - AcceptableLocation = true; - break; - } - } - - if (!AcceptableLocation) - return; - } else if (DiagLevel == Diagnostic::Note) { - // Don't apply fix-it modifications in notes. - return; - } - // Make sure that we can perform all of the modifications we // in this diagnostic. bool CanRewrite = Info.getNumFixItHints() > 0; @@ -197,3 +163,5 @@ void FixItRewriter::Diag(FullSourceLoc Loc, unsigned DiagID) { Diags.Report(Loc, DiagID); Diags.setClient(this); } + +FixItPathRewriter::~FixItPathRewriter() {} diff --git a/lib/Frontend/FrontendActions.cpp b/lib/Frontend/FrontendActions.cpp index e2b2fd7deb..6cd960be20 100644 --- a/lib/Frontend/FrontendActions.cpp +++ b/lib/Frontend/FrontendActions.cpp @@ -19,6 +19,7 @@ #include "clang/Frontend/FixItRewriter.h" #include "clang/Frontend/FrontendDiagnostic.h" #include "clang/Frontend/Utils.h" +#include "llvm/ADT/OwningPtr.h" #include "llvm/Support/raw_ostream.h" using namespace clang; @@ -113,85 +114,36 @@ ASTConsumer *FixItAction::CreateASTConsumer(CompilerInstance &CI, return new ASTConsumer(); } -/// AddFixItLocations - Add any individual user specified "fix-it" locations, -/// and return true on success. -static bool AddFixItLocations(CompilerInstance &CI, - FixItRewriter &FixItRewrite) { - const std::vector<ParsedSourceLocation> &Locs = - CI.getFrontendOpts().FixItLocations; - for (unsigned i = 0, e = Locs.size(); i != e; ++i) { - const FileEntry *File = CI.getFileManager().getFile(Locs[i].FileName); - if (!File) { - CI.getDiagnostics().Report(diag::err_fe_unable_to_find_fixit_file) - << Locs[i].FileName; - return false; - } - - RequestedSourceLocation Requested; - Requested.File = File; - Requested.Line = Locs[i].Line; - Requested.Column = Locs[i].Column; - FixItRewrite.addFixItLocation(Requested); - } +class FixItActionSuffixInserter : public FixItPathRewriter { + std::string NewSuffix; - const std::string &OutputFile = CI.getFrontendOpts().OutputFile; - if (Locs.empty() && !OutputFile.empty()) { - // FIXME: we will issue "FIX-IT applied suggested code changes" for every - // input, but only the main file will actually be rewritten. - const std::vector<std::pair<FrontendOptions::InputKind, std::string> > &Inputs = - CI.getFrontendOpts().Inputs; - for (unsigned i = 0, e = Inputs.size(); i != e; ++i) { - const FileEntry *File = CI.getFileManager().getFile(Inputs[i].second); - assert(File && "Input file not found in FileManager"); - RequestedSourceLocation Requested; - Requested.File = File; - Requested.Line = 0; - Requested.Column = 0; - FixItRewrite.addFixItLocation(Requested); - } - } +public: + explicit FixItActionSuffixInserter(std::string NewSuffix) + : NewSuffix(NewSuffix) {} - return true; -} + std::string RewriteFilename(const std::string &Filename) { + llvm::sys::Path Path(Filename); + std::string Suffix = Path.getSuffix(); + Path.eraseSuffix(); + Path.appendSuffix(NewSuffix + "." + Suffix); + return Path.c_str(); + } +}; bool FixItAction::BeginSourceFileAction(CompilerInstance &CI, llvm::StringRef Filename) { + const FrontendOptions &FEOpts = getCompilerInstance().getFrontendOpts(); + if (!FEOpts.FixItSuffix.empty()) { + PathRewriter.reset(new FixItActionSuffixInserter(FEOpts.FixItSuffix)); + } else { + PathRewriter.reset(); + } Rewriter.reset(new FixItRewriter(CI.getDiagnostics(), CI.getSourceManager(), - CI.getLangOpts())); - if (!AddFixItLocations(CI, *Rewriter)) - return false; - + CI.getLangOpts(), PathRewriter.get())); return true; } void FixItAction::EndSourceFileAction() { - const FrontendOptions &FEOpts = getCompilerInstance().getFrontendOpts(); - if (!FEOpts.OutputFile.empty()) { - // When called with 'clang -fixit -o filename' output only the main file. - - const SourceManager &SM = getCompilerInstance().getSourceManager(); - FileID MainFileID = SM.getMainFileID(); - if (!Rewriter->IsModified(MainFileID)) { - getCompilerInstance().getDiagnostics().Report( - diag::note_fixit_main_file_unchanged); - return; - } - - llvm::OwningPtr<llvm::raw_ostream> OwnedStream; - llvm::raw_ostream *OutFile; - if (FEOpts.OutputFile == "-") { - OutFile = &llvm::outs(); - } else { - std::string Err; - OutFile = new llvm::raw_fd_ostream(FEOpts.OutputFile.c_str(), Err, - llvm::raw_fd_ostream::F_Binary); - OwnedStream.reset(OutFile); - } - - Rewriter->WriteFixedFile(MainFileID, *OutFile); - return; - } - // Otherwise rewrite all files. Rewriter->WriteFixedFiles(); } |