diff options
author | Eli Friedman <eli.friedman@gmail.com> | 2009-05-18 22:20:00 +0000 |
---|---|---|
committer | Eli Friedman <eli.friedman@gmail.com> | 2009-05-18 22:20:00 +0000 |
commit | 94cf21e282c7be4e440efc91940326f6c10cdca5 (patch) | |
tree | 275ac3000388f6d2e018197b055289278e61d6d5 /clang/tools | |
parent | 479858749b5fbdcc744c943ddb51d957f356a936 (diff) | |
download | bcm5719-llvm-94cf21e282c7be4e440efc91940326f6c10cdca5.tar.gz bcm5719-llvm-94cf21e282c7be4e440efc91940326f6c10cdca5.zip |
Refactor ASTConsumers to take a raw_ostream instead of a filename where
appropriate. There shouldn't be any significant functionality change.
llvm-svn: 72052
Diffstat (limited to 'clang/tools')
-rw-r--r-- | clang/tools/clang-cc/ASTConsumers.h | 15 | ||||
-rw-r--r-- | clang/tools/clang-cc/Backend.cpp | 41 | ||||
-rw-r--r-- | clang/tools/clang-cc/GeneratePCH.cpp | 25 | ||||
-rw-r--r-- | clang/tools/clang-cc/HTMLPrint.cpp | 28 | ||||
-rw-r--r-- | clang/tools/clang-cc/RewriteBlocks.cpp | 11 | ||||
-rw-r--r-- | clang/tools/clang-cc/RewriteObjC.cpp | 41 | ||||
-rw-r--r-- | clang/tools/clang-cc/clang-cc.cpp | 182 |
7 files changed, 156 insertions, 187 deletions
diff --git a/clang/tools/clang-cc/ASTConsumers.h b/clang/tools/clang-cc/ASTConsumers.h index f270f363421..bb31e5c1588 100644 --- a/clang/tools/clang-cc/ASTConsumers.h +++ b/clang/tools/clang-cc/ASTConsumers.h @@ -36,7 +36,7 @@ class LangOptions; // original C code. The output is intended to be in a format such that // clang could re-parse the output back into the same AST, but the // implementation is still incomplete. -ASTConsumer *CreateASTPrinter(llvm::raw_ostream* OS = NULL); +ASTConsumer *CreateASTPrinter(llvm::raw_ostream* OS); // AST dumper: dumps the raw AST in human-readable form to stderr; this is // intended for debugging. A normal dump is done with FullDump = false; @@ -56,7 +56,7 @@ ASTConsumer *CreateDeclContextPrinter(); // ObjC rewriter: attempts tp rewrite ObjC constructs into pure C code. // This is considered experimental, and only works with Apple's ObjC runtime. ASTConsumer *CreateCodeRewriterTest(const std::string& InFile, - const std::string& OutFile, + llvm::raw_ostream* OS, Diagnostic &Diags, const LangOptions &LOpts); @@ -73,24 +73,23 @@ ASTConsumer *CreateBackendConsumer(BackendAction Action, Diagnostic &Diags, const LangOptions &Features, const CompileOptions &CompileOpts, - const std::string &InFile, - const std::string &OutFile); + const std::string &ModuleID, + llvm::raw_ostream *OS); // HTML printer: uses the rewriter to convert source code to HTML with // syntax highlighting suitable for viewing in a web-browser. -ASTConsumer* CreateHTMLPrinter(const std::string &OutFile, Diagnostic &D, +ASTConsumer* CreateHTMLPrinter(llvm::raw_ostream *OS, Diagnostic &D, Preprocessor *PP, PreprocessorFactory *PPF); // PCH generator: generates a precompiled header file; this file can be // used later with the PCHReader (clang-cc option -include-pch) // to speed up compile times. ASTConsumer *CreatePCHGenerator(const Preprocessor &PP, - const std::string &OutFile); + llvm::raw_ostream *OS); // Block rewriter: rewrites code using the Apple blocks extension to pure -// C code. +// C code. Output is always sent to stdout. ASTConsumer *CreateBlockRewriter(const std::string &InFile, - const std::string &OutFile, Diagnostic &Diags, const LangOptions &LangOpts); diff --git a/clang/tools/clang-cc/Backend.cpp b/clang/tools/clang-cc/Backend.cpp index ebee66167d0..2988ae697a6 100644 --- a/clang/tools/clang-cc/Backend.cpp +++ b/clang/tools/clang-cc/Backend.cpp @@ -42,8 +42,7 @@ namespace { class VISIBILITY_HIDDEN BackendConsumer : public ASTConsumer { BackendAction Action; CompileOptions CompileOpts; - const std::string &InputFile; - std::string OutputFile; + llvm::raw_ostream *AsmOutStream; ASTContext *Context; Timer LLVMIRGeneration; @@ -53,7 +52,6 @@ namespace { llvm::Module *TheModule; llvm::TargetData *TheTargetData; - llvm::raw_ostream *AsmOutStream; mutable llvm::ModuleProvider *ModuleProvider; mutable FunctionPassManager *CodeGenPasses; @@ -78,15 +76,14 @@ namespace { public: BackendConsumer(BackendAction action, Diagnostic &Diags, const LangOptions &langopts, const CompileOptions &compopts, - const std::string &infile, const std::string &outfile) : + const std::string &infile, llvm::raw_ostream* OS) : Action(action), CompileOpts(compopts), - InputFile(infile), - OutputFile(outfile), + AsmOutStream(OS), LLVMIRGeneration("LLVM IR Generation Time"), CodeGenerationTime("Code Generation Time"), - Gen(CreateLLVMCodeGen(Diags, InputFile, compopts)), - TheModule(0), TheTargetData(0), AsmOutStream(0), ModuleProvider(0), + Gen(CreateLLVMCodeGen(Diags, infile, compopts)), + TheModule(0), TheTargetData(0), ModuleProvider(0), CodeGenPasses(0), PerModulePasses(0), PerFunctionPasses(0) { // Enable -time-passes if -ftime-report is enabled. @@ -94,7 +91,6 @@ namespace { } ~BackendConsumer() { - delete AsmOutStream; delete TheTargetData; delete ModuleProvider; delete CodeGenPasses; @@ -196,28 +192,6 @@ bool BackendConsumer::AddEmitPasses(std::string &Error) { if (Action == Backend_EmitNothing) return true; - if (OutputFile == "-" || (InputFile == "-" && OutputFile.empty())) { - AsmOutStream = new raw_stdout_ostream(); - sys::Program::ChangeStdoutToBinary(); - } else { - if (OutputFile.empty()) { - llvm::sys::Path Path(InputFile); - Path.eraseSuffix(); - if (Action == Backend_EmitBC) { - Path.appendSuffix("bc"); - } else if (Action == Backend_EmitLL) { - Path.appendSuffix("ll"); - } else { - Path.appendSuffix("s"); - } - OutputFile = Path.toString(); - } - - AsmOutStream = new raw_fd_ostream(OutputFile.c_str(), true, Error); - if (!Error.empty()) - return false; - } - if (Action == Backend_EmitBC) { getPerModulePasses()->add(createBitcodeWriterPass(*AsmOutStream)); } else if (Action == Backend_EmitLL) { @@ -435,7 +409,6 @@ ASTConsumer *clang::CreateBackendConsumer(BackendAction Action, const LangOptions &LangOpts, const CompileOptions &CompileOpts, const std::string& InFile, - const std::string& OutFile) { - return new BackendConsumer(Action, Diags, LangOpts, CompileOpts, - InFile, OutFile); + llvm::raw_ostream* OS) { + return new BackendConsumer(Action, Diags, LangOpts, CompileOpts, InFile, OS); } diff --git a/clang/tools/clang-cc/GeneratePCH.cpp b/clang/tools/clang-cc/GeneratePCH.cpp index 9bc5ded7157..62ab0ec010b 100644 --- a/clang/tools/clang-cc/GeneratePCH.cpp +++ b/clang/tools/clang-cc/GeneratePCH.cpp @@ -32,19 +32,19 @@ using namespace llvm; namespace { class VISIBILITY_HIDDEN PCHGenerator : public SemaConsumer { const Preprocessor &PP; - std::string OutFile; + llvm::raw_ostream *Out; Sema *SemaPtr; MemorizeStatCalls *StatCalls; // owned by the FileManager public: - explicit PCHGenerator(const Preprocessor &PP, const std::string &OutFile); + explicit PCHGenerator(const Preprocessor &PP, llvm::raw_ostream *Out); virtual void InitializeSema(Sema &S) { SemaPtr = &S; } virtual void HandleTranslationUnit(ASTContext &Ctx); }; } -PCHGenerator::PCHGenerator(const Preprocessor &PP, const std::string &OutFile) - : PP(PP), OutFile(OutFile), SemaPtr(0), StatCalls(0) { +PCHGenerator::PCHGenerator(const Preprocessor &PP, llvm::raw_ostream *OS) + : PP(PP), Out(OS), SemaPtr(0), StatCalls(0) { // Install a stat() listener to keep track of all of the stat() // calls. @@ -65,23 +65,14 @@ void PCHGenerator::HandleTranslationUnit(ASTContext &Ctx) { assert(SemaPtr && "No Sema?"); Writer.WritePCH(*SemaPtr, StatCalls); - // Open up the PCH file. - std::string ErrMsg; - llvm::raw_fd_ostream Out(OutFile.c_str(), true, ErrMsg); - - if (!ErrMsg.empty()) { - llvm::errs() << "PCH error: " << ErrMsg << "\n"; - return; - } - // Write the generated bitstream to "Out". - Out.write((char *)&Buffer.front(), Buffer.size()); + Out->write((char *)&Buffer.front(), Buffer.size()); // Make sure it hits disk now. - Out.flush(); + Out->flush(); } ASTConsumer *clang::CreatePCHGenerator(const Preprocessor &PP, - const std::string &OutFile) { - return new PCHGenerator(PP, OutFile); + llvm::raw_ostream *OS) { + return new PCHGenerator(PP, OS); } diff --git a/clang/tools/clang-cc/HTMLPrint.cpp b/clang/tools/clang-cc/HTMLPrint.cpp index 0e15973939e..71121095aed 100644 --- a/clang/tools/clang-cc/HTMLPrint.cpp +++ b/clang/tools/clang-cc/HTMLPrint.cpp @@ -30,25 +30,25 @@ using namespace clang; namespace { class HTMLPrinter : public ASTConsumer { Rewriter R; - std::string OutFilename; + llvm::raw_ostream *Out; Diagnostic &Diags; Preprocessor *PP; PreprocessorFactory *PPF; public: - HTMLPrinter(const std::string &OutFile, Diagnostic &D, Preprocessor *pp, + HTMLPrinter(llvm::raw_ostream *OS, Diagnostic &D, Preprocessor *pp, PreprocessorFactory* ppf) - : OutFilename(OutFile), Diags(D), PP(pp), PPF(ppf) {} + : Out(OS), Diags(D), PP(pp), PPF(ppf) {} virtual ~HTMLPrinter(); void Initialize(ASTContext &context); }; } -ASTConsumer* clang::CreateHTMLPrinter(const std::string &OutFile, +ASTConsumer* clang::CreateHTMLPrinter(llvm::raw_ostream *OS, Diagnostic &D, Preprocessor *PP, PreprocessorFactory* PPF) { - return new HTMLPrinter(OutFile, D, PP, PPF); + return new HTMLPrinter(OS, D, PP, PPF); } void HTMLPrinter::Initialize(ASTContext &context) { @@ -73,25 +73,11 @@ HTMLPrinter::~HTMLPrinter() { if (PP) html::SyntaxHighlight(R, FID, *PP); if (PPF) html::HighlightMacros(R, FID, *PP); html::EscapeText(R, FID, false, true); - - // Open the output. - FILE *OutputFILE; - if (OutFilename.empty() || OutFilename == "-") - OutputFILE = stdout; - else { - OutputFILE = fopen(OutFilename.c_str(), "w+"); - if (OutputFILE == 0) { - fprintf(stderr, "Error opening output file '%s'.\n", OutFilename.c_str()); - exit(1); - } - } - + // Emit the HTML. const RewriteBuffer &RewriteBuf = R.getEditBuffer(FID); char *Buffer = (char*)malloc(RewriteBuf.size()); std::copy(RewriteBuf.begin(), RewriteBuf.end(), Buffer); - fwrite(Buffer, 1, RewriteBuf.size(), OutputFILE); + Out->write(Buffer, RewriteBuf.size()); free(Buffer); - - if (OutputFILE != stdout) fclose(OutputFILE); } diff --git a/clang/tools/clang-cc/RewriteBlocks.cpp b/clang/tools/clang-cc/RewriteBlocks.cpp index f9ed0ecc095..135f4a70bfa 100644 --- a/clang/tools/clang-cc/RewriteBlocks.cpp +++ b/clang/tools/clang-cc/RewriteBlocks.cpp @@ -57,12 +57,10 @@ class RewriteBlocks : public ASTConsumer { ObjCMethodDecl *CurMethodDef; bool IsHeader; - std::string InFileName; - std::string OutFileName; std::string Preamble; public: - RewriteBlocks(std::string inFile, std::string outFile, Diagnostic &D, + RewriteBlocks(std::string inFile, Diagnostic &D, const LangOptions &LOpts); ~RewriteBlocks() { // Get the buffer corresponding to MainFileID. @@ -169,12 +167,10 @@ static bool IsHeaderFile(const std::string &Filename) { return Ext == "h" || Ext == "hh" || Ext == "H"; } -RewriteBlocks::RewriteBlocks(std::string inFile, std::string outFile, +RewriteBlocks::RewriteBlocks(std::string inFile, Diagnostic &D, const LangOptions &LOpts) : Diags(D), LangOpts(LOpts) { IsHeader = IsHeaderFile(inFile); - InFileName = inFile; - OutFileName = outFile; CurFunctionDef = 0; CurMethodDef = 0; RewriteFailedDiag = Diags.getCustomDiagID(Diagnostic::Warning, @@ -182,10 +178,9 @@ RewriteBlocks::RewriteBlocks(std::string inFile, std::string outFile, } ASTConsumer *clang::CreateBlockRewriter(const std::string& InFile, - const std::string& OutFile, Diagnostic &Diags, const LangOptions &LangOpts) { - return new RewriteBlocks(InFile, OutFile, Diags, LangOpts); + return new RewriteBlocks(InFile, Diags, LangOpts); } void RewriteBlocks::Initialize(ASTContext &context) { diff --git a/clang/tools/clang-cc/RewriteObjC.cpp b/clang/tools/clang-cc/RewriteObjC.cpp index 37dd52485d6..b104747c00c 100644 --- a/clang/tools/clang-cc/RewriteObjC.cpp +++ b/clang/tools/clang-cc/RewriteObjC.cpp @@ -93,7 +93,7 @@ namespace { bool IsHeader; std::string InFileName; - std::string OutFileName; + llvm::raw_ostream* OutFile; std::string Preamble; @@ -136,7 +136,7 @@ namespace { } void HandleTopLevelSingleDecl(Decl *D); void HandleDeclInMainFile(Decl *D); - RewriteObjC(std::string inFile, std::string outFile, + RewriteObjC(std::string inFile, llvm::raw_ostream *OS, Diagnostic &D, const LangOptions &LOpts); ~RewriteObjC() {} @@ -416,12 +416,10 @@ static bool IsHeaderFile(const std::string &Filename) { return Ext == "h" || Ext == "hh" || Ext == "H"; } -RewriteObjC::RewriteObjC(std::string inFile, std::string outFile, +RewriteObjC::RewriteObjC(std::string inFile, llvm::raw_ostream* OS, Diagnostic &D, const LangOptions &LOpts) - : Diags(D), LangOpts(LOpts) { + : Diags(D), LangOpts(LOpts), InFileName(inFile), OutFile(OS) { IsHeader = IsHeaderFile(inFile); - InFileName = inFile; - OutFileName = outFile; RewriteFailedDiag = Diags.getCustomDiagID(Diagnostic::Warning, "rewriting sub-expression within a macro (may not be correct)"); TryFinallyContainsReturnDiag = Diags.getCustomDiagID(Diagnostic::Warning, @@ -430,10 +428,10 @@ RewriteObjC::RewriteObjC(std::string inFile, std::string outFile, } ASTConsumer *clang::CreateCodeRewriterTest(const std::string& InFile, - const std::string& OutFile, + llvm::raw_ostream* OS, Diagnostic &Diags, const LangOptions &LOpts) { - return new RewriteObjC(InFile, OutFile, Diags, LOpts); + return new RewriteObjC(InFile, OS, Diags, LOpts); } void RewriteObjC::Initialize(ASTContext &context) { @@ -4654,33 +4652,6 @@ void RewriteObjC::HandleTranslationUnit(ASTContext &C) { if (Diags.hasErrorOccurred()) return; - - // Create the output file. - - llvm::OwningPtr<llvm::raw_ostream> OwnedStream; - llvm::raw_ostream *OutFile; - if (OutFileName == "-") { - OutFile = &llvm::outs(); - } else if (!OutFileName.empty()) { - std::string Err; - OutFile = new llvm::raw_fd_ostream(OutFileName.c_str(), - // set binary mode (critical for Windoze) - true, - Err); - OwnedStream.reset(OutFile); - } else if (InFileName == "-") { - OutFile = &llvm::outs(); - } else { - llvm::sys::Path Path(InFileName); - Path.eraseSuffix(); - Path.appendSuffix("cpp"); - std::string Err; - OutFile = new llvm::raw_fd_ostream(Path.toString().c_str(), - // set binary mode (critical for Windoze) - true, - Err); - OwnedStream.reset(OutFile); - } RewriteInclude(); diff --git a/clang/tools/clang-cc/clang-cc.cpp b/clang/tools/clang-cc/clang-cc.cpp index 588ed2f76a1..6aaa471efea 100644 --- a/clang/tools/clang-cc/clang-cc.cpp +++ b/clang/tools/clang-cc/clang-cc.cpp @@ -59,10 +59,12 @@ #include "llvm/Support/MemoryBuffer.h" #include "llvm/Support/PluginLoader.h" #include "llvm/Support/PrettyStackTrace.h" +#include "llvm/Support/Streams.h" #include "llvm/Support/Timer.h" #include "llvm/System/Host.h" #include "llvm/System/Path.h" #include "llvm/System/Process.h" +#include "llvm/System/Program.h" #include "llvm/System/Signals.h" #include <cstdlib> #if HAVE_SYS_TYPES_H @@ -1569,101 +1571,141 @@ static void SetUpBuildDumpLog(unsigned argc, char **argv, // Main driver //===----------------------------------------------------------------------===// -/// CreateASTConsumer - Create the ASTConsumer for the corresponding program -/// action. These consumers can operate on both ASTs that are freshly -/// parsed from source files as well as those deserialized from Bitcode. -/// Note that PP and PPF may be null here. -static ASTConsumer *CreateASTConsumer(const std::string& InFile, - Diagnostic& Diag, FileManager& FileMgr, - const LangOptions& LangOpts, - const llvm::StringMap<bool>& Features, - Preprocessor *PP, - PreprocessorFactory *PPF) { - switch (ProgAction) { +static llvm::raw_ostream* ComputeOutFile(const std::string& InFile, + const char* Extension, + bool Binary, + llvm::sys::Path& OutPath) { + llvm::raw_ostream* Ret; + bool UseStdout = false; + std::string OutFile; + if (OutputFile == "-" || (OutputFile.empty() && InFile == "-")) { + UseStdout = true; + } else if (!OutputFile.empty()) { + OutFile = OutputFile; + } else if (Extension) { + llvm::sys::Path Path(InFile); + Path.eraseSuffix(); + Path.appendSuffix(Extension); + OutFile = Path.toString(); + } else { + UseStdout = true; + } + + if (UseStdout) { + Ret = new llvm::raw_stdout_ostream(); + if (Binary) + llvm::sys::Program::ChangeStdoutToBinary(); + } else { + std::string Error; + Ret = new llvm::raw_fd_ostream(OutFile.c_str(), Binary, Error); + if (!Error.empty()) { + // FIXME: Don't fail this way. + llvm::cerr << "ERROR: " << Error << "\n"; + ::exit(1); + } + OutPath = OutFile; + } + + return Ret; +} + +/// ProcessInputFile - Process a single input file with the specified state. +/// +static void ProcessInputFile(Preprocessor &PP, PreprocessorFactory &PPF, + const std::string &InFile, ProgActions PA, + const llvm::StringMap<bool> &Features) { + llvm::OwningPtr<llvm::raw_ostream> OS; + llvm::OwningPtr<ASTConsumer> Consumer; + bool ClearSourceMgr = false; + FixItRewriter *FixItRewrite = 0; + bool CompleteTranslationUnit = true; + llvm::sys::Path OutPath; + + switch (PA) { default: - return NULL; - + fprintf(stderr, "Unexpected program action!\n"); + HadErrors = true; + return; + case ASTPrint: - return CreateASTPrinter(); + OS.reset(ComputeOutFile(InFile, 0, false, OutPath)); + Consumer.reset(CreateASTPrinter(OS.get())); + break; case ASTDump: - return CreateASTDumper(false); + Consumer.reset(CreateASTDumper(false)); + break; case ASTDumpFull: - return CreateASTDumper(true); + Consumer.reset(CreateASTDumper(true)); + break; case ASTView: - return CreateASTViewer(); + Consumer.reset(CreateASTViewer()); + break; case PrintDeclContext: - return CreateDeclContextPrinter(); - + Consumer.reset(CreateDeclContextPrinter()); + break; + case EmitHTML: - return CreateHTMLPrinter(OutputFile, Diag, PP, PPF); + OS.reset(ComputeOutFile(InFile, 0, true, OutPath)); + Consumer.reset(CreateHTMLPrinter(OS.get(), PP.getDiagnostics(), &PP, &PPF)); + break; case InheritanceView: - return CreateInheritanceViewer(InheritanceViewCls); - + Consumer.reset(CreateInheritanceViewer(InheritanceViewCls)); + break; + case EmitAssembly: case EmitLLVM: case EmitBC: case EmitLLVMOnly: { BackendAction Act; - if (ProgAction == EmitAssembly) + if (ProgAction == EmitAssembly) { Act = Backend_EmitAssembly; - else if (ProgAction == EmitLLVM) + OS.reset(ComputeOutFile(InFile, "s", true, OutPath)); + } else if (ProgAction == EmitLLVM) { Act = Backend_EmitLL; - else if (ProgAction == EmitLLVMOnly) + OS.reset(ComputeOutFile(InFile, "ll", true, OutPath)); + } else if (ProgAction == EmitLLVMOnly) { Act = Backend_EmitNothing; - else + } else { Act = Backend_EmitBC; - + OS.reset(ComputeOutFile(InFile, "bc", true, OutPath)); + } + CompileOptions Opts; - InitializeCompileOptions(Opts, LangOpts, Features); - return CreateBackendConsumer(Act, Diag, LangOpts, Opts, - InFile, OutputFile); + InitializeCompileOptions(Opts, PP.getLangOptions(), Features); + Consumer.reset(CreateBackendConsumer(Act, PP.getDiagnostics(), + PP.getLangOptions(), Opts, InFile, + OS.get())); + break; } case GeneratePCH: - return CreatePCHGenerator(*PP, OutputFile); + OS.reset(ComputeOutFile(InFile, 0, true, OutPath)); + Consumer.reset(CreatePCHGenerator(PP, OS.get())); + CompleteTranslationUnit = false; + break; case RewriteObjC: - return CreateCodeRewriterTest(InFile, OutputFile, Diag, LangOpts); + OS.reset(ComputeOutFile(InFile, "cpp", true, OutPath)); + Consumer.reset(CreateCodeRewriterTest(InFile, OS.get(), + PP.getDiagnostics(), + PP.getLangOptions())); + break; case RewriteBlocks: - return CreateBlockRewriter(InFile, OutputFile, Diag, LangOpts); - - case RunAnalysis: - return CreateAnalysisConsumer(Diag, PP, PPF, LangOpts, OutputFile); - } -} - -/// ProcessInputFile - Process a single input file with the specified state. -/// -static void ProcessInputFile(Preprocessor &PP, PreprocessorFactory &PPF, - const std::string &InFile, ProgActions PA, - const llvm::StringMap<bool> &Features) { - llvm::OwningPtr<ASTConsumer> Consumer; - bool ClearSourceMgr = false; - FixItRewriter *FixItRewrite = 0; - bool CompleteTranslationUnit = true; - - switch (PA) { - default: - Consumer.reset(CreateASTConsumer(InFile, PP.getDiagnostics(), - PP.getFileManager(), PP.getLangOptions(), - Features, &PP, &PPF)); - - if (!Consumer) { - fprintf(stderr, "Unexpected program action!\n"); - HadErrors = true; - return; - } + Consumer.reset(CreateBlockRewriter(InFile, PP.getDiagnostics(), + PP.getLangOptions())); + break; - if (ProgAction == GeneratePCH) - CompleteTranslationUnit = false; + case RunAnalysis: + Consumer.reset(CreateAnalysisConsumer(PP.getDiagnostics(), &PP, &PPF, + PP.getLangOptions(), OutputFile)); break; - + case DumpRawTokens: { llvm::TimeRegion Timer(ClangFrontendTimer); SourceManager &SM = PP.getSourceManager(); @@ -1869,7 +1911,7 @@ static void ProcessInputFile(Preprocessor &PP, PreprocessorFactory &PPF, ContextOwner.take(); else ContextOwner.reset(); // Delete ASTContext - + if (VerifyDiagnostics) if (CheckDiagnostics(PP)) exit(1); @@ -1891,6 +1933,18 @@ static void ProcessInputFile(Preprocessor &PP, PreprocessorFactory &PPF, if (DisableFree) Consumer.take(); + else + Consumer.reset(); + + // Always delete the output stream because we don't want to leak file + // handles. Also, we don't want to try to erase an open file. + OS.reset(); + + if ((HadErrors || (PP.getDiagnostics().getNumErrors() != 0)) && + !OutPath.isEmpty()) { + // If we had errors, try to erase the output file. + OutPath.eraseFromDisk(); + } } static llvm::cl::list<std::string> |