Frontend: Simplify ownership model for clang's output streams.

This changes the CompilerInstance::createOutputFile function to return
a std::unique_ptr<llvm::raw_ostream>, rather than an llvm::raw_ostream
implicitly owned by the CompilerInstance. This in most cases required that
I move ownership of the output stream to the relevant ASTConsumer.

The motivation for this change is to allow BackendConsumer to be a client
of interfaces such as D20268 which take ownership of the output stream.

Differential Revision: http://reviews.llvm.org/D21537

llvm-svn: 275507
This commit is contained in:
Peter Collingbourne 2016-07-15 00:55:40 +00:00
parent 38c5318662
commit 03f8907f65
20 changed files with 235 additions and 251 deletions

View File

@ -37,7 +37,8 @@ namespace clang {
void EmitBackendOutput(DiagnosticsEngine &Diags, const CodeGenOptions &CGOpts, void EmitBackendOutput(DiagnosticsEngine &Diags, const CodeGenOptions &CGOpts,
const TargetOptions &TOpts, const LangOptions &LOpts, const TargetOptions &TOpts, const LangOptions &LOpts,
const llvm::DataLayout &TDesc, llvm::Module *M, const llvm::DataLayout &TDesc, llvm::Module *M,
BackendAction Action, raw_pwrite_stream *OS); BackendAction Action,
std::unique_ptr<raw_pwrite_stream> OS);
void EmbedBitcode(llvm::Module *M, const CodeGenOptions &CGOpts, void EmbedBitcode(llvm::Module *M, const CodeGenOptions &CGOpts,
llvm::MemoryBufferRef Buf); llvm::MemoryBufferRef Buf);

View File

@ -22,9 +22,11 @@ class ObjectFilePCHContainerWriter : public PCHContainerWriter {
/// Return an ASTConsumer that can be chained with a /// Return an ASTConsumer that can be chained with a
/// PCHGenerator that produces a wrapper file format /// PCHGenerator that produces a wrapper file format
/// that also contains full debug info for the module. /// that also contains full debug info for the module.
std::unique_ptr<ASTConsumer> CreatePCHContainerGenerator( std::unique_ptr<ASTConsumer>
CompilerInstance &CI, const std::string &MainFileName, CreatePCHContainerGenerator(CompilerInstance &CI,
const std::string &OutputFileName, llvm::raw_pwrite_stream *OS, const std::string &MainFileName,
const std::string &OutputFileName,
std::unique_ptr<llvm::raw_pwrite_stream> OS,
std::shared_ptr<PCHBuffer> Buffer) const override; std::shared_ptr<PCHBuffer> Buffer) const override;
}; };

View File

@ -31,7 +31,7 @@ class TargetOptions;
// original C code. The output is intended to be in a format such that // 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 // clang could re-parse the output back into the same AST, but the
// implementation is still incomplete. // implementation is still incomplete.
std::unique_ptr<ASTConsumer> CreateASTPrinter(raw_ostream *OS, std::unique_ptr<ASTConsumer> CreateASTPrinter(std::unique_ptr<raw_ostream> OS,
StringRef FilterString); StringRef FilterString);
// AST dumper: dumps the raw AST in human-readable form to stderr; this is // AST dumper: dumps the raw AST in human-readable form to stderr; this is

View File

@ -155,15 +155,10 @@ class CompilerInstance : public ModuleLoader {
struct OutputFile { struct OutputFile {
std::string Filename; std::string Filename;
std::string TempFilename; std::string TempFilename;
std::unique_ptr<raw_ostream> OS;
OutputFile(std::string filename, std::string tempFilename, OutputFile(std::string filename, std::string tempFilename)
std::unique_ptr<raw_ostream> OS) : Filename(std::move(filename)), TempFilename(std::move(tempFilename)) {
: Filename(std::move(filename)), TempFilename(std::move(tempFilename)), }
OS(std::move(OS)) {}
OutputFile(OutputFile &&O)
: Filename(std::move(O.Filename)),
TempFilename(std::move(O.TempFilename)), OS(std::move(O.OS)) {}
}; };
/// If the output doesn't support seeking (terminal, pipe). we switch /// If the output doesn't support seeking (terminal, pipe). we switch
@ -577,8 +572,8 @@ public:
/// \param OutFile - The output file info. /// \param OutFile - The output file info.
void addOutputFile(OutputFile &&OutFile); void addOutputFile(OutputFile &&OutFile);
/// clearOutputFiles - Clear the output file list, destroying the contained /// clearOutputFiles - Clear the output file list. The underlying output
/// output streams. /// streams must have been closed beforehand.
/// ///
/// \param EraseFiles - If true, attempt to erase the files from disk. /// \param EraseFiles - If true, attempt to erase the files from disk.
void clearOutputFiles(bool EraseFiles); void clearOutputFiles(bool EraseFiles);
@ -685,18 +680,17 @@ public:
/// atomically replace the target output on success). /// atomically replace the target output on success).
/// ///
/// \return - Null on error. /// \return - Null on error.
raw_pwrite_stream *createDefaultOutputFile(bool Binary = true, std::unique_ptr<raw_pwrite_stream>
StringRef BaseInput = "", createDefaultOutputFile(bool Binary = true, StringRef BaseInput = "",
StringRef Extension = ""); StringRef Extension = "");
/// Create a new output file and add it to the list of tracked output files, /// Create a new output file and add it to the list of tracked output files,
/// optionally deriving the output path name. /// optionally deriving the output path name.
/// ///
/// \return - Null on error. /// \return - Null on error.
raw_pwrite_stream *createOutputFile(StringRef OutputPath, bool Binary, std::unique_ptr<raw_pwrite_stream>
bool RemoveFileOnSignal, createOutputFile(StringRef OutputPath, bool Binary, bool RemoveFileOnSignal,
StringRef BaseInput, StringRef Extension, StringRef BaseInput, StringRef Extension, bool UseTemporary,
bool UseTemporary,
bool CreateMissingDirectories = false); bool CreateMissingDirectories = false);
/// Create a new output file, optionally deriving the output path name. /// Create a new output file, optionally deriving the output path name.
@ -731,7 +725,7 @@ public:
bool CreateMissingDirectories, std::string *ResultPathName, bool CreateMissingDirectories, std::string *ResultPathName,
std::string *TempPathName); std::string *TempPathName);
llvm::raw_null_ostream *createNullOutputFile(); std::unique_ptr<raw_pwrite_stream> createNullOutputFile();
/// } /// }
/// @name Initialization Utility Methods /// @name Initialization Utility Methods

View File

@ -85,7 +85,7 @@ public:
/// create the PCHGenerator instance returned by CreateASTConsumer. /// create the PCHGenerator instance returned by CreateASTConsumer.
/// ///
/// \returns true if an error occurred, false otherwise. /// \returns true if an error occurred, false otherwise.
static raw_pwrite_stream * static std::unique_ptr<raw_pwrite_stream>
ComputeASTConsumerArguments(CompilerInstance &CI, StringRef InFile, ComputeASTConsumerArguments(CompilerInstance &CI, StringRef InFile,
std::string &Sysroot, std::string &OutputFile); std::string &Sysroot, std::string &OutputFile);
}; };
@ -117,10 +117,9 @@ public:
/// create the PCHGenerator instance returned by CreateASTConsumer. /// create the PCHGenerator instance returned by CreateASTConsumer.
/// ///
/// \returns true if an error occurred, false otherwise. /// \returns true if an error occurred, false otherwise.
raw_pwrite_stream *ComputeASTConsumerArguments(CompilerInstance &CI, std::unique_ptr<raw_pwrite_stream>
StringRef InFile, ComputeASTConsumerArguments(CompilerInstance &CI, StringRef InFile,
std::string &Sysroot, std::string &Sysroot, std::string &OutputFile);
std::string &OutputFile);
}; };
class SyntaxOnlyAction : public ASTFrontendAction { class SyntaxOnlyAction : public ASTFrontendAction {

View File

@ -46,9 +46,11 @@ public:
/// Return an ASTConsumer that can be chained with a /// Return an ASTConsumer that can be chained with a
/// PCHGenerator that produces a wrapper file format containing a /// PCHGenerator that produces a wrapper file format containing a
/// serialized AST bitstream. /// serialized AST bitstream.
virtual std::unique_ptr<ASTConsumer> CreatePCHContainerGenerator( virtual std::unique_ptr<ASTConsumer>
CompilerInstance &CI, const std::string &MainFileName, CreatePCHContainerGenerator(CompilerInstance &CI,
const std::string &OutputFileName, llvm::raw_pwrite_stream *OS, const std::string &MainFileName,
const std::string &OutputFileName,
std::unique_ptr<llvm::raw_pwrite_stream> OS,
std::shared_ptr<PCHBuffer> Buffer) const = 0; std::shared_ptr<PCHBuffer> Buffer) const = 0;
}; };
@ -73,9 +75,11 @@ class RawPCHContainerWriter : public PCHContainerWriter {
/// Return an ASTConsumer that can be chained with a /// Return an ASTConsumer that can be chained with a
/// PCHGenerator that writes the module to a flat file. /// PCHGenerator that writes the module to a flat file.
std::unique_ptr<ASTConsumer> CreatePCHContainerGenerator( std::unique_ptr<ASTConsumer>
CompilerInstance &CI, const std::string &MainFileName, CreatePCHContainerGenerator(CompilerInstance &CI,
const std::string &OutputFileName, llvm::raw_pwrite_stream *OS, const std::string &MainFileName,
const std::string &OutputFileName,
std::unique_ptr<llvm::raw_pwrite_stream> OS,
std::shared_ptr<PCHBuffer> Buffer) const override; std::shared_ptr<PCHBuffer> Buffer) const override;
}; };

View File

@ -28,17 +28,18 @@ class Preprocessor;
// ObjC rewriter: attempts to rewrite ObjC constructs into pure C code. // ObjC rewriter: attempts to rewrite ObjC constructs into pure C code.
// This is considered experimental, and only works with Apple's ObjC runtime. // This is considered experimental, and only works with Apple's ObjC runtime.
std::unique_ptr<ASTConsumer> std::unique_ptr<ASTConsumer>
CreateObjCRewriter(const std::string &InFile, raw_ostream *OS, CreateObjCRewriter(const std::string &InFile, std::unique_ptr<raw_ostream> OS,
DiagnosticsEngine &Diags, const LangOptions &LOpts, DiagnosticsEngine &Diags, const LangOptions &LOpts,
bool SilenceRewriteMacroWarning); bool SilenceRewriteMacroWarning);
std::unique_ptr<ASTConsumer> std::unique_ptr<ASTConsumer>
CreateModernObjCRewriter(const std::string &InFile, raw_ostream *OS, CreateModernObjCRewriter(const std::string &InFile,
std::unique_ptr<raw_ostream> OS,
DiagnosticsEngine &Diags, const LangOptions &LOpts, DiagnosticsEngine &Diags, const LangOptions &LOpts,
bool SilenceRewriteMacroWarning, bool LineInfo); bool SilenceRewriteMacroWarning, bool LineInfo);
/// CreateHTMLPrinter - Create an AST consumer which rewrites source code to /// CreateHTMLPrinter - Create an AST consumer which rewrites source code to
/// HTML with syntax highlighting suitable for viewing in a web-browser. /// HTML with syntax highlighting suitable for viewing in a web-browser.
std::unique_ptr<ASTConsumer> CreateHTMLPrinter(raw_ostream *OS, std::unique_ptr<ASTConsumer> CreateHTMLPrinter(std::unique_ptr<raw_ostream> OS,
Preprocessor &PP, Preprocessor &PP,
bool SyntaxHighlight = true, bool SyntaxHighlight = true,
bool HighlightMacros = true); bool HighlightMacros = true);

View File

@ -61,9 +61,7 @@ class EmitAssemblyHelper {
Timer CodeGenerationTime; Timer CodeGenerationTime;
mutable legacy::PassManager *CodeGenPasses; std::unique_ptr<raw_pwrite_stream> OS;
mutable legacy::PassManager *PerModulePasses;
mutable legacy::FunctionPassManager *PerFunctionPasses;
private: private:
TargetIRAnalysis getTargetIRAnalysis() const { TargetIRAnalysis getTargetIRAnalysis() const {
@ -73,73 +71,44 @@ private:
return TargetIRAnalysis(); return TargetIRAnalysis();
} }
legacy::PassManager *getCodeGenPasses() const {
if (!CodeGenPasses) {
CodeGenPasses = new legacy::PassManager();
CodeGenPasses->add(
createTargetTransformInfoWrapperPass(getTargetIRAnalysis()));
}
return CodeGenPasses;
}
legacy::PassManager *getPerModulePasses() const {
if (!PerModulePasses) {
PerModulePasses = new legacy::PassManager();
PerModulePasses->add(
createTargetTransformInfoWrapperPass(getTargetIRAnalysis()));
}
return PerModulePasses;
}
legacy::FunctionPassManager *getPerFunctionPasses() const {
if (!PerFunctionPasses) {
PerFunctionPasses = new legacy::FunctionPassManager(TheModule);
PerFunctionPasses->add(
createTargetTransformInfoWrapperPass(getTargetIRAnalysis()));
}
return PerFunctionPasses;
}
/// Set LLVM command line options passed through -backend-option. /// Set LLVM command line options passed through -backend-option.
void setCommandLineOpts(); void setCommandLineOpts();
void CreatePasses(ModuleSummaryIndex *ModuleSummary); void CreatePasses(legacy::PassManager &MPM, legacy::FunctionPassManager &FPM,
ModuleSummaryIndex *ModuleSummary);
/// Generates the TargetMachine. /// Generates the TargetMachine.
/// Returns Null if it is unable to create the target machine. /// Leaves TM unchanged if it is unable to create the target machine.
/// Some of our clang tests specify triples which are not built /// Some of our clang tests specify triples which are not built
/// into clang. This is okay because these tests check the generated /// into clang. This is okay because these tests check the generated
/// IR, and they require DataLayout which depends on the triple. /// IR, and they require DataLayout which depends on the triple.
/// In this case, we allow this method to fail and not report an error. /// In this case, we allow this method to fail and not report an error.
/// When MustCreateTM is used, we print an error if we are unable to load /// When MustCreateTM is used, we print an error if we are unable to load
/// the requested target. /// the requested target.
TargetMachine *CreateTargetMachine(bool MustCreateTM); void CreateTargetMachine(bool MustCreateTM);
/// Add passes necessary to emit assembly or LLVM IR. /// Add passes necessary to emit assembly or LLVM IR.
/// ///
/// \return True on success. /// \return True on success.
bool AddEmitPasses(BackendAction Action, raw_pwrite_stream &OS); bool AddEmitPasses(legacy::PassManager &CodeGenPasses, BackendAction Action,
raw_pwrite_stream &OS);
public: public:
EmitAssemblyHelper(DiagnosticsEngine &_Diags, const CodeGenOptions &CGOpts, EmitAssemblyHelper(DiagnosticsEngine &_Diags, const CodeGenOptions &CGOpts,
const clang::TargetOptions &TOpts, const clang::TargetOptions &TOpts,
const LangOptions &LOpts, Module *M) const LangOptions &LOpts, Module *M)
: Diags(_Diags), CodeGenOpts(CGOpts), TargetOpts(TOpts), LangOpts(LOpts), : Diags(_Diags), CodeGenOpts(CGOpts), TargetOpts(TOpts), LangOpts(LOpts),
TheModule(M), CodeGenerationTime("Code Generation Time"), TheModule(M), CodeGenerationTime("Code Generation Time") {}
CodeGenPasses(nullptr), PerModulePasses(nullptr),
PerFunctionPasses(nullptr) {}
~EmitAssemblyHelper() { ~EmitAssemblyHelper() {
delete CodeGenPasses;
delete PerModulePasses;
delete PerFunctionPasses;
if (CodeGenOpts.DisableFree) if (CodeGenOpts.DisableFree)
BuryPointer(std::move(TM)); BuryPointer(std::move(TM));
} }
std::unique_ptr<TargetMachine> TM; std::unique_ptr<TargetMachine> TM;
void EmitAssembly(BackendAction Action, raw_pwrite_stream *OS); void EmitAssembly(BackendAction Action,
std::unique_ptr<raw_pwrite_stream> OS);
}; };
// We need this wrapper to access LangOpts and CGOpts from extension functions // We need this wrapper to access LangOpts and CGOpts from extension functions
@ -311,7 +280,9 @@ static void addSymbolRewriterPass(const CodeGenOptions &Opts,
MPM->add(createRewriteSymbolsPass(DL)); MPM->add(createRewriteSymbolsPass(DL));
} }
void EmitAssemblyHelper::CreatePasses(ModuleSummaryIndex *ModuleSummary) { void EmitAssemblyHelper::CreatePasses(legacy::PassManager &MPM,
legacy::FunctionPassManager &FPM,
ModuleSummaryIndex *ModuleSummary) {
if (CodeGenOpts.DisableLLVMPasses) if (CodeGenOpts.DisableLLVMPasses)
return; return;
@ -362,13 +333,11 @@ void EmitAssemblyHelper::CreatePasses(ModuleSummaryIndex *ModuleSummary) {
PMBuilder.PrepareForLTO = CodeGenOpts.PrepareForLTO; PMBuilder.PrepareForLTO = CodeGenOpts.PrepareForLTO;
PMBuilder.RerollLoops = CodeGenOpts.RerollLoops; PMBuilder.RerollLoops = CodeGenOpts.RerollLoops;
legacy::PassManager *MPM = getPerModulePasses();
// If we are performing a ThinLTO importing compile, invoke the LTO // If we are performing a ThinLTO importing compile, invoke the LTO
// pipeline and pass down the in-memory module summary index. // pipeline and pass down the in-memory module summary index.
if (ModuleSummary) { if (ModuleSummary) {
PMBuilder.ModuleSummary = ModuleSummary; PMBuilder.ModuleSummary = ModuleSummary;
PMBuilder.populateThinLTOPassManager(*MPM); PMBuilder.populateThinLTOPassManager(MPM);
return; return;
} }
@ -452,13 +421,12 @@ void EmitAssemblyHelper::CreatePasses(ModuleSummaryIndex *ModuleSummary) {
} }
// Set up the per-function pass manager. // Set up the per-function pass manager.
legacy::FunctionPassManager *FPM = getPerFunctionPasses();
if (CodeGenOpts.VerifyModule) if (CodeGenOpts.VerifyModule)
FPM->add(createVerifierPass()); FPM.add(createVerifierPass());
// Set up the per-module pass manager. // Set up the per-module pass manager.
if (!CodeGenOpts.RewriteMapFiles.empty()) if (!CodeGenOpts.RewriteMapFiles.empty())
addSymbolRewriterPass(CodeGenOpts, MPM); addSymbolRewriterPass(CodeGenOpts, &MPM);
if (!CodeGenOpts.DisableGCov && if (!CodeGenOpts.DisableGCov &&
(CodeGenOpts.EmitGcovArcs || CodeGenOpts.EmitGcovNotes)) { (CodeGenOpts.EmitGcovArcs || CodeGenOpts.EmitGcovNotes)) {
@ -473,16 +441,16 @@ void EmitAssemblyHelper::CreatePasses(ModuleSummaryIndex *ModuleSummary) {
Options.FunctionNamesInData = Options.FunctionNamesInData =
!CodeGenOpts.CoverageNoFunctionNamesInData; !CodeGenOpts.CoverageNoFunctionNamesInData;
Options.ExitBlockBeforeBody = CodeGenOpts.CoverageExitBlockBeforeBody; Options.ExitBlockBeforeBody = CodeGenOpts.CoverageExitBlockBeforeBody;
MPM->add(createGCOVProfilerPass(Options)); MPM.add(createGCOVProfilerPass(Options));
if (CodeGenOpts.getDebugInfo() == codegenoptions::NoDebugInfo) if (CodeGenOpts.getDebugInfo() == codegenoptions::NoDebugInfo)
MPM->add(createStripSymbolsPass(true)); MPM.add(createStripSymbolsPass(true));
} }
if (CodeGenOpts.hasProfileClangInstr()) { if (CodeGenOpts.hasProfileClangInstr()) {
InstrProfOptions Options; InstrProfOptions Options;
Options.NoRedZone = CodeGenOpts.DisableRedZone; Options.NoRedZone = CodeGenOpts.DisableRedZone;
Options.InstrProfileOutput = CodeGenOpts.InstrProfileOutput; Options.InstrProfileOutput = CodeGenOpts.InstrProfileOutput;
MPM->add(createInstrProfilingLegacyPass(Options)); MPM.add(createInstrProfilingLegacyPass(Options));
} }
if (CodeGenOpts.hasProfileIRInstr()) { if (CodeGenOpts.hasProfileIRInstr()) {
if (!CodeGenOpts.InstrProfileOutput.empty()) if (!CodeGenOpts.InstrProfileOutput.empty())
@ -494,14 +462,14 @@ void EmitAssemblyHelper::CreatePasses(ModuleSummaryIndex *ModuleSummary) {
PMBuilder.PGOInstrUse = CodeGenOpts.ProfileInstrumentUsePath; PMBuilder.PGOInstrUse = CodeGenOpts.ProfileInstrumentUsePath;
if (!CodeGenOpts.SampleProfileFile.empty()) { if (!CodeGenOpts.SampleProfileFile.empty()) {
MPM->add(createPruneEHPass()); MPM.add(createPruneEHPass());
MPM->add(createSampleProfileLoaderPass(CodeGenOpts.SampleProfileFile)); MPM.add(createSampleProfileLoaderPass(CodeGenOpts.SampleProfileFile));
PMBuilder.addExtension(PassManagerBuilder::EP_EarlyAsPossible, PMBuilder.addExtension(PassManagerBuilder::EP_EarlyAsPossible,
addCleanupPassesForSampleProfiler); addCleanupPassesForSampleProfiler);
} }
PMBuilder.populateFunctionPassManager(*FPM); PMBuilder.populateFunctionPassManager(FPM);
PMBuilder.populateModulePassManager(*MPM); PMBuilder.populateModulePassManager(MPM);
} }
void EmitAssemblyHelper::setCommandLineOpts() { void EmitAssemblyHelper::setCommandLineOpts() {
@ -522,7 +490,7 @@ void EmitAssemblyHelper::setCommandLineOpts() {
BackendArgs.data()); BackendArgs.data());
} }
TargetMachine *EmitAssemblyHelper::CreateTargetMachine(bool MustCreateTM) { void EmitAssemblyHelper::CreateTargetMachine(bool MustCreateTM) {
// Create the TargetMachine for generating code. // Create the TargetMachine for generating code.
std::string Error; std::string Error;
std::string Triple = TheModule->getTargetTriple(); std::string Triple = TheModule->getTargetTriple();
@ -530,7 +498,7 @@ TargetMachine *EmitAssemblyHelper::CreateTargetMachine(bool MustCreateTM) {
if (!TheTarget) { if (!TheTarget) {
if (MustCreateTM) if (MustCreateTM)
Diags.Report(diag::err_fe_unable_to_create_target) << Error; Diags.Report(diag::err_fe_unable_to_create_target) << Error;
return nullptr; return;
} }
unsigned CodeModel = unsigned CodeModel =
@ -637,24 +605,18 @@ TargetMachine *EmitAssemblyHelper::CreateTargetMachine(bool MustCreateTM) {
Options.MCOptions.AsmVerbose = CodeGenOpts.AsmVerbose; Options.MCOptions.AsmVerbose = CodeGenOpts.AsmVerbose;
Options.MCOptions.ABIName = TargetOpts.ABI; Options.MCOptions.ABIName = TargetOpts.ABI;
TargetMachine *TM = TheTarget->createTargetMachine(Triple, TargetOpts.CPU, TM.reset(TheTarget->createTargetMachine(Triple, TargetOpts.CPU, FeaturesStr,
FeaturesStr, Options, Options, RM, CM, OptLevel));
RM, CM, OptLevel);
return TM;
} }
bool EmitAssemblyHelper::AddEmitPasses(BackendAction Action, bool EmitAssemblyHelper::AddEmitPasses(legacy::PassManager &CodeGenPasses,
BackendAction Action,
raw_pwrite_stream &OS) { raw_pwrite_stream &OS) {
// Create the code generator passes.
legacy::PassManager *PM = getCodeGenPasses();
// Add LibraryInfo. // Add LibraryInfo.
llvm::Triple TargetTriple(TheModule->getTargetTriple()); llvm::Triple TargetTriple(TheModule->getTargetTriple());
std::unique_ptr<TargetLibraryInfoImpl> TLII( std::unique_ptr<TargetLibraryInfoImpl> TLII(
createTLII(TargetTriple, CodeGenOpts)); createTLII(TargetTriple, CodeGenOpts));
PM->add(new TargetLibraryInfoWrapperPass(*TLII)); CodeGenPasses.add(new TargetLibraryInfoWrapperPass(*TLII));
// Normal mode, emit a .s or .o file by running the code generator. Note, // Normal mode, emit a .s or .o file by running the code generator. Note,
// this also adds codegenerator level optimization passes. // this also adds codegenerator level optimization passes.
@ -670,9 +632,9 @@ bool EmitAssemblyHelper::AddEmitPasses(BackendAction Action,
// "codegen" passes so that it isn't run multiple times when there is // "codegen" passes so that it isn't run multiple times when there is
// inlining happening. // inlining happening.
if (CodeGenOpts.OptimizationLevel > 0) if (CodeGenOpts.OptimizationLevel > 0)
PM->add(createObjCARCContractPass()); CodeGenPasses.add(createObjCARCContractPass());
if (TM->addPassesToEmitFile(*PM, OS, CGFT, if (TM->addPassesToEmitFile(CodeGenPasses, OS, CGFT,
/*DisableVerify=*/!CodeGenOpts.VerifyModule)) { /*DisableVerify=*/!CodeGenOpts.VerifyModule)) {
Diags.Report(diag::err_fe_unable_to_interface_with_target); Diags.Report(diag::err_fe_unable_to_interface_with_target);
return false; return false;
@ -682,7 +644,7 @@ bool EmitAssemblyHelper::AddEmitPasses(BackendAction Action,
} }
void EmitAssemblyHelper::EmitAssembly(BackendAction Action, void EmitAssemblyHelper::EmitAssembly(BackendAction Action,
raw_pwrite_stream *OS) { std::unique_ptr<raw_pwrite_stream> OS) {
TimeRegion Region(llvm::TimePassesIsEnabled ? &CodeGenerationTime : nullptr); TimeRegion Region(llvm::TimePassesIsEnabled ? &CodeGenerationTime : nullptr);
setCommandLineOpts(); setCommandLineOpts();
@ -690,8 +652,7 @@ void EmitAssemblyHelper::EmitAssembly(BackendAction Action,
bool UsesCodeGen = (Action != Backend_EmitNothing && bool UsesCodeGen = (Action != Backend_EmitNothing &&
Action != Backend_EmitBC && Action != Backend_EmitBC &&
Action != Backend_EmitLL); Action != Backend_EmitLL);
if (!TM) CreateTargetMachine(UsesCodeGen);
TM.reset(CreateTargetMachine(UsesCodeGen));
if (UsesCodeGen && !TM) if (UsesCodeGen && !TM)
return; return;
@ -718,25 +679,37 @@ void EmitAssemblyHelper::EmitAssembly(BackendAction Action,
assert(ModuleSummary && "Expected non-empty module summary index"); assert(ModuleSummary && "Expected non-empty module summary index");
} }
CreatePasses(ModuleSummary.get()); legacy::PassManager PerModulePasses;
PerModulePasses.add(
createTargetTransformInfoWrapperPass(getTargetIRAnalysis()));
legacy::FunctionPassManager PerFunctionPasses(TheModule);
PerFunctionPasses.add(
createTargetTransformInfoWrapperPass(getTargetIRAnalysis()));
CreatePasses(PerModulePasses, PerFunctionPasses, ModuleSummary.get());
legacy::PassManager CodeGenPasses;
CodeGenPasses.add(
createTargetTransformInfoWrapperPass(getTargetIRAnalysis()));
switch (Action) { switch (Action) {
case Backend_EmitNothing: case Backend_EmitNothing:
break; break;
case Backend_EmitBC: case Backend_EmitBC:
getPerModulePasses()->add(createBitcodeWriterPass( PerModulePasses.add(createBitcodeWriterPass(
*OS, CodeGenOpts.EmitLLVMUseLists, CodeGenOpts.EmitSummaryIndex, *OS, CodeGenOpts.EmitLLVMUseLists, CodeGenOpts.EmitSummaryIndex,
CodeGenOpts.EmitSummaryIndex)); CodeGenOpts.EmitSummaryIndex));
break; break;
case Backend_EmitLL: case Backend_EmitLL:
getPerModulePasses()->add( PerModulePasses.add(
createPrintModulePass(*OS, "", CodeGenOpts.EmitLLVMUseLists)); createPrintModulePass(*OS, "", CodeGenOpts.EmitLLVMUseLists));
break; break;
default: default:
if (!AddEmitPasses(Action, *OS)) if (!AddEmitPasses(CodeGenPasses, Action, *OS))
return; return;
} }
@ -746,24 +719,24 @@ void EmitAssemblyHelper::EmitAssembly(BackendAction Action,
// Run passes. For now we do all passes at once, but eventually we // Run passes. For now we do all passes at once, but eventually we
// would like to have the option of streaming code generation. // would like to have the option of streaming code generation.
if (PerFunctionPasses) { {
PrettyStackTraceString CrashInfo("Per-function optimization"); PrettyStackTraceString CrashInfo("Per-function optimization");
PerFunctionPasses->doInitialization(); PerFunctionPasses.doInitialization();
for (Function &F : *TheModule) for (Function &F : *TheModule)
if (!F.isDeclaration()) if (!F.isDeclaration())
PerFunctionPasses->run(F); PerFunctionPasses.run(F);
PerFunctionPasses->doFinalization(); PerFunctionPasses.doFinalization();
} }
if (PerModulePasses) { {
PrettyStackTraceString CrashInfo("Per-module optimization passes"); PrettyStackTraceString CrashInfo("Per-module optimization passes");
PerModulePasses->run(*TheModule); PerModulePasses.run(*TheModule);
} }
if (CodeGenPasses) { {
PrettyStackTraceString CrashInfo("Code generation"); PrettyStackTraceString CrashInfo("Code generation");
CodeGenPasses->run(*TheModule); CodeGenPasses.run(*TheModule);
} }
} }
@ -772,10 +745,10 @@ void clang::EmitBackendOutput(DiagnosticsEngine &Diags,
const clang::TargetOptions &TOpts, const clang::TargetOptions &TOpts,
const LangOptions &LOpts, const llvm::DataLayout &TDesc, const LangOptions &LOpts, const llvm::DataLayout &TDesc,
Module *M, BackendAction Action, Module *M, BackendAction Action,
raw_pwrite_stream *OS) { std::unique_ptr<raw_pwrite_stream> OS) {
EmitAssemblyHelper AsmHelper(Diags, CGOpts, TOpts, LOpts, M); EmitAssemblyHelper AsmHelper(Diags, CGOpts, TOpts, LOpts, M);
AsmHelper.EmitAssembly(Action, OS); AsmHelper.EmitAssembly(Action, std::move(OS));
// Verify clang's TargetInfo DataLayout against the LLVM TargetMachine's // Verify clang's TargetInfo DataLayout against the LLVM TargetMachine's
// DataLayout. // DataLayout.

View File

@ -46,7 +46,7 @@ namespace clang {
const CodeGenOptions &CodeGenOpts; const CodeGenOptions &CodeGenOpts;
const TargetOptions &TargetOpts; const TargetOptions &TargetOpts;
const LangOptions &LangOpts; const LangOptions &LangOpts;
raw_pwrite_stream *AsmOutStream; std::unique_ptr<raw_pwrite_stream> AsmOutStream;
ASTContext *Context; ASTContext *Context;
Timer LLVMIRGeneration; Timer LLVMIRGeneration;
@ -68,11 +68,12 @@ namespace clang {
const TargetOptions &TargetOpts, const LangOptions &LangOpts, const TargetOptions &TargetOpts, const LangOptions &LangOpts,
bool TimePasses, const std::string &InFile, bool TimePasses, const std::string &InFile,
const SmallVectorImpl<std::pair<unsigned, llvm::Module *>> &LinkModules, const SmallVectorImpl<std::pair<unsigned, llvm::Module *>> &LinkModules,
raw_pwrite_stream *OS, LLVMContext &C, std::unique_ptr<raw_pwrite_stream> OS, LLVMContext &C,
CoverageSourceInfo *CoverageInfo = nullptr) CoverageSourceInfo *CoverageInfo = nullptr)
: Diags(Diags), Action(Action), CodeGenOpts(CodeGenOpts), : Diags(Diags), Action(Action), CodeGenOpts(CodeGenOpts),
TargetOpts(TargetOpts), LangOpts(LangOpts), AsmOutStream(OS), TargetOpts(TargetOpts), LangOpts(LangOpts),
Context(nullptr), LLVMIRGeneration("LLVM IR Generation Time"), AsmOutStream(std::move(OS)), Context(nullptr),
LLVMIRGeneration("LLVM IR Generation Time"),
Gen(CreateLLVMCodeGen(Diags, InFile, HeaderSearchOpts, PPOpts, Gen(CreateLLVMCodeGen(Diags, InFile, HeaderSearchOpts, PPOpts,
CodeGenOpts, C, CoverageInfo)) { CodeGenOpts, C, CoverageInfo)) {
llvm::TimePassesIsEnabled = TimePasses; llvm::TimePassesIsEnabled = TimePasses;
@ -177,7 +178,7 @@ namespace clang {
EmitBackendOutput(Diags, CodeGenOpts, TargetOpts, LangOpts, EmitBackendOutput(Diags, CodeGenOpts, TargetOpts, LangOpts,
C.getTargetInfo().getDataLayout(), C.getTargetInfo().getDataLayout(),
getModule(), Action, AsmOutStream); getModule(), Action, std::move(AsmOutStream));
Ctx.setInlineAsmDiagnosticHandler(OldHandler, OldContext); Ctx.setInlineAsmDiagnosticHandler(OldHandler, OldContext);
@ -691,7 +692,7 @@ llvm::LLVMContext *CodeGenAction::takeLLVMContext() {
return VMContext; return VMContext;
} }
static raw_pwrite_stream * static std::unique_ptr<raw_pwrite_stream>
GetOutputStream(CompilerInstance &CI, StringRef InFile, BackendAction Action) { GetOutputStream(CompilerInstance &CI, StringRef InFile, BackendAction Action) {
switch (Action) { switch (Action) {
case Backend_EmitAssembly: case Backend_EmitAssembly:
@ -714,7 +715,7 @@ GetOutputStream(CompilerInstance &CI, StringRef InFile, BackendAction Action) {
std::unique_ptr<ASTConsumer> std::unique_ptr<ASTConsumer>
CodeGenAction::CreateASTConsumer(CompilerInstance &CI, StringRef InFile) { CodeGenAction::CreateASTConsumer(CompilerInstance &CI, StringRef InFile) {
BackendAction BA = static_cast<BackendAction>(Act); BackendAction BA = static_cast<BackendAction>(Act);
raw_pwrite_stream *OS = GetOutputStream(CI, InFile, BA); std::unique_ptr<raw_pwrite_stream> OS = GetOutputStream(CI, InFile, BA);
if (BA != Backend_EmitNothing && !OS) if (BA != Backend_EmitNothing && !OS)
return nullptr; return nullptr;
@ -754,7 +755,7 @@ CodeGenAction::CreateASTConsumer(CompilerInstance &CI, StringRef InFile) {
BA, CI.getDiagnostics(), CI.getHeaderSearchOpts(), BA, CI.getDiagnostics(), CI.getHeaderSearchOpts(),
CI.getPreprocessorOpts(), CI.getCodeGenOpts(), CI.getTargetOpts(), CI.getPreprocessorOpts(), CI.getCodeGenOpts(), CI.getTargetOpts(),
CI.getLangOpts(), CI.getFrontendOpts().ShowTimers, InFile, LinkModules, CI.getLangOpts(), CI.getFrontendOpts().ShowTimers, InFile, LinkModules,
OS, *VMContext, CoverageInfo)); std::move(OS), *VMContext, CoverageInfo));
BEConsumer = Result.get(); BEConsumer = Result.get();
return std::move(Result); return std::move(Result);
} }
@ -786,7 +787,8 @@ void CodeGenAction::ExecuteAction() {
if (getCurrentFileKind() == IK_LLVM_IR) { if (getCurrentFileKind() == IK_LLVM_IR) {
BackendAction BA = static_cast<BackendAction>(Act); BackendAction BA = static_cast<BackendAction>(Act);
CompilerInstance &CI = getCompilerInstance(); CompilerInstance &CI = getCompilerInstance();
raw_pwrite_stream *OS = GetOutputStream(CI, getCurrentFile(), BA); std::unique_ptr<raw_pwrite_stream> OS =
GetOutputStream(CI, getCurrentFile(), BA);
if (BA != Backend_EmitNothing && !OS) if (BA != Backend_EmitNothing && !OS)
return; return;
@ -843,7 +845,7 @@ void CodeGenAction::ExecuteAction() {
EmitBackendOutput(CI.getDiagnostics(), CI.getCodeGenOpts(), TargetOpts, EmitBackendOutput(CI.getDiagnostics(), CI.getCodeGenOpts(), TargetOpts,
CI.getLangOpts(), CI.getTarget().getDataLayout(), CI.getLangOpts(), CI.getTarget().getDataLayout(),
TheModule.get(), BA, OS); TheModule.get(), BA, std::move(OS));
return; return;
} }

View File

@ -55,7 +55,7 @@ class PCHContainerGenerator : public ASTConsumer {
std::unique_ptr<llvm::LLVMContext> VMContext; std::unique_ptr<llvm::LLVMContext> VMContext;
std::unique_ptr<llvm::Module> M; std::unique_ptr<llvm::Module> M;
std::unique_ptr<CodeGen::CodeGenModule> Builder; std::unique_ptr<CodeGen::CodeGenModule> Builder;
raw_pwrite_stream *OS; std::unique_ptr<raw_pwrite_stream> OS;
std::shared_ptr<PCHBuffer> Buffer; std::shared_ptr<PCHBuffer> Buffer;
/// Visit every type and emit debug info for it. /// Visit every type and emit debug info for it.
@ -138,15 +138,15 @@ class PCHContainerGenerator : public ASTConsumer {
public: public:
PCHContainerGenerator(CompilerInstance &CI, const std::string &MainFileName, PCHContainerGenerator(CompilerInstance &CI, const std::string &MainFileName,
const std::string &OutputFileName, const std::string &OutputFileName,
raw_pwrite_stream *OS, std::unique_ptr<raw_pwrite_stream> OS,
std::shared_ptr<PCHBuffer> Buffer) std::shared_ptr<PCHBuffer> Buffer)
: Diags(CI.getDiagnostics()), MainFileName(MainFileName), : Diags(CI.getDiagnostics()), MainFileName(MainFileName),
OutputFileName(OutputFileName), Ctx(nullptr), OutputFileName(OutputFileName), Ctx(nullptr),
MMap(CI.getPreprocessor().getHeaderSearchInfo().getModuleMap()), MMap(CI.getPreprocessor().getHeaderSearchInfo().getModuleMap()),
HeaderSearchOpts(CI.getHeaderSearchOpts()), HeaderSearchOpts(CI.getHeaderSearchOpts()),
PreprocessorOpts(CI.getPreprocessorOpts()), PreprocessorOpts(CI.getPreprocessorOpts()),
TargetOpts(CI.getTargetOpts()), LangOpts(CI.getLangOpts()), OS(OS), TargetOpts(CI.getTargetOpts()), LangOpts(CI.getLangOpts()),
Buffer(std::move(Buffer)) { OS(std::move(OS)), Buffer(std::move(Buffer)) {
// The debug info output isn't affected by CodeModel and // The debug info output isn't affected by CodeModel and
// ThreadModel, but the backend expects them to be nonempty. // ThreadModel, but the backend expects them to be nonempty.
CodeGenOpts.CodeModel = "default"; CodeGenOpts.CodeModel = "default";
@ -281,20 +281,18 @@ public:
DEBUG({ DEBUG({
// Print the IR for the PCH container to the debug output. // Print the IR for the PCH container to the debug output.
llvm::SmallString<0> Buffer; llvm::SmallString<0> Buffer;
llvm::raw_svector_ostream OS(Buffer); clang::EmitBackendOutput(
clang::EmitBackendOutput(Diags, CodeGenOpts, TargetOpts, LangOpts, Diags, CodeGenOpts, TargetOpts, LangOpts,
Ctx.getTargetInfo().getDataLayout(), M.get(), Ctx.getTargetInfo().getDataLayout(), M.get(),
BackendAction::Backend_EmitLL, &OS); BackendAction::Backend_EmitLL,
llvm::make_unique<llvm::raw_svector_ostream>(Buffer));
llvm::dbgs() << Buffer; llvm::dbgs() << Buffer;
}); });
// Use the LLVM backend to emit the pch container. // Use the LLVM backend to emit the pch container.
clang::EmitBackendOutput(Diags, CodeGenOpts, TargetOpts, LangOpts, clang::EmitBackendOutput(Diags, CodeGenOpts, TargetOpts, LangOpts,
Ctx.getTargetInfo().getDataLayout(), M.get(), Ctx.getTargetInfo().getDataLayout(), M.get(),
BackendAction::Backend_EmitObj, OS); BackendAction::Backend_EmitObj, std::move(OS));
// Make sure the pch container hits disk.
OS->flush();
// Free the memory for the temporary buffer. // Free the memory for the temporary buffer.
llvm::SmallVector<char, 0> Empty; llvm::SmallVector<char, 0> Empty;
@ -307,10 +305,11 @@ public:
std::unique_ptr<ASTConsumer> std::unique_ptr<ASTConsumer>
ObjectFilePCHContainerWriter::CreatePCHContainerGenerator( ObjectFilePCHContainerWriter::CreatePCHContainerGenerator(
CompilerInstance &CI, const std::string &MainFileName, CompilerInstance &CI, const std::string &MainFileName,
const std::string &OutputFileName, llvm::raw_pwrite_stream *OS, const std::string &OutputFileName,
std::unique_ptr<llvm::raw_pwrite_stream> OS,
std::shared_ptr<PCHBuffer> Buffer) const { std::shared_ptr<PCHBuffer> Buffer) const {
return llvm::make_unique<PCHContainerGenerator>(CI, MainFileName, return llvm::make_unique<PCHContainerGenerator>(
OutputFileName, OS, Buffer); CI, MainFileName, OutputFileName, std::move(OS), Buffer);
} }
void ObjectFilePCHContainerReader::ExtractPCH( void ObjectFilePCHContainerReader::ExtractPCH(

View File

@ -35,9 +35,9 @@ namespace {
typedef RecursiveASTVisitor<ASTPrinter> base; typedef RecursiveASTVisitor<ASTPrinter> base;
public: public:
ASTPrinter(raw_ostream *Out = nullptr, bool Dump = false, ASTPrinter(std::unique_ptr<raw_ostream> Out = nullptr, bool Dump = false,
StringRef FilterString = "", bool DumpLookups = false) StringRef FilterString = "", bool DumpLookups = false)
: Out(Out ? *Out : llvm::outs()), Dump(Dump), : Out(Out ? *Out : llvm::outs()), OwnedOut(std::move(Out)), Dump(Dump),
FilterString(FilterString), DumpLookups(DumpLookups) {} FilterString(FilterString), DumpLookups(DumpLookups) {}
void HandleTranslationUnit(ASTContext &Context) override { void HandleTranslationUnit(ASTContext &Context) override {
@ -94,6 +94,7 @@ namespace {
} }
raw_ostream &Out; raw_ostream &Out;
std::unique_ptr<raw_ostream> OwnedOut;
bool Dump; bool Dump;
std::string FilterString; std::string FilterString;
bool DumpLookups; bool DumpLookups;
@ -122,9 +123,11 @@ namespace {
}; };
} // end anonymous namespace } // end anonymous namespace
std::unique_ptr<ASTConsumer> clang::CreateASTPrinter(raw_ostream *Out, std::unique_ptr<ASTConsumer>
clang::CreateASTPrinter(std::unique_ptr<raw_ostream> Out,
StringRef FilterString) { StringRef FilterString) {
return llvm::make_unique<ASTPrinter>(Out, /*Dump=*/false, FilterString); return llvm::make_unique<ASTPrinter>(std::move(Out), /*Dump=*/false,
FilterString);
} }
std::unique_ptr<ASTConsumer> clang::CreateASTDumper(StringRef FilterString, std::unique_ptr<ASTConsumer> clang::CreateASTDumper(StringRef FilterString,

View File

@ -920,17 +920,17 @@ class PrecompilePreambleConsumer : public PCHGenerator {
unsigned &Hash; unsigned &Hash;
std::vector<Decl *> TopLevelDecls; std::vector<Decl *> TopLevelDecls;
PrecompilePreambleAction *Action; PrecompilePreambleAction *Action;
raw_ostream *Out; std::unique_ptr<raw_ostream> Out;
public: public:
PrecompilePreambleConsumer(ASTUnit &Unit, PrecompilePreambleAction *Action, PrecompilePreambleConsumer(ASTUnit &Unit, PrecompilePreambleAction *Action,
const Preprocessor &PP, StringRef isysroot, const Preprocessor &PP, StringRef isysroot,
raw_ostream *Out) std::unique_ptr<raw_ostream> Out)
: PCHGenerator(PP, "", nullptr, isysroot, std::make_shared<PCHBuffer>(), : PCHGenerator(PP, "", nullptr, isysroot, std::make_shared<PCHBuffer>(),
ArrayRef<llvm::IntrusiveRefCntPtr<ModuleFileExtension>>(), ArrayRef<llvm::IntrusiveRefCntPtr<ModuleFileExtension>>(),
/*AllowASTWithErrors=*/true), /*AllowASTWithErrors=*/true),
Unit(Unit), Hash(Unit.getCurrentTopLevelHashValue()), Action(Action), Unit(Unit), Hash(Unit.getCurrentTopLevelHashValue()), Action(Action),
Out(Out) { Out(std::move(Out)) {
Hash = 0; Hash = 0;
} }
@ -982,8 +982,9 @@ PrecompilePreambleAction::CreateASTConsumer(CompilerInstance &CI,
StringRef InFile) { StringRef InFile) {
std::string Sysroot; std::string Sysroot;
std::string OutputFile; std::string OutputFile;
raw_ostream *OS = GeneratePCHAction::ComputeASTConsumerArguments( std::unique_ptr<raw_ostream> OS =
CI, InFile, Sysroot, OutputFile); GeneratePCHAction::ComputeASTConsumerArguments(CI, InFile, Sysroot,
OutputFile);
if (!OS) if (!OS)
return nullptr; return nullptr;
@ -994,7 +995,7 @@ PrecompilePreambleAction::CreateASTConsumer(CompilerInstance &CI,
llvm::make_unique<MacroDefinitionTrackerPPCallbacks>( llvm::make_unique<MacroDefinitionTrackerPPCallbacks>(
Unit.getCurrentTopLevelHashValue())); Unit.getCurrentTopLevelHashValue()));
return llvm::make_unique<PrecompilePreambleConsumer>( return llvm::make_unique<PrecompilePreambleConsumer>(
Unit, this, CI.getPreprocessor(), Sysroot, OS); Unit, this, CI.getPreprocessor(), Sysroot, std::move(OS));
} }
static bool isNonDriverDiag(const StoredDiagnostic &StoredDiag) { static bool isNonDriverDiag(const StoredDiagnostic &StoredDiag) {

View File

@ -542,15 +542,11 @@ void CompilerInstance::createSema(TranslationUnitKind TUKind,
// Output Files // Output Files
void CompilerInstance::addOutputFile(OutputFile &&OutFile) { void CompilerInstance::addOutputFile(OutputFile &&OutFile) {
assert(OutFile.OS && "Attempt to add empty stream to output list!");
OutputFiles.push_back(std::move(OutFile)); OutputFiles.push_back(std::move(OutFile));
} }
void CompilerInstance::clearOutputFiles(bool EraseFiles) { void CompilerInstance::clearOutputFiles(bool EraseFiles) {
for (OutputFile &OF : OutputFiles) { for (OutputFile &OF : OutputFiles) {
// Manually close the stream before we rename it.
OF.OS.reset();
if (!OF.TempFilename.empty()) { if (!OF.TempFilename.empty()) {
if (EraseFiles) { if (EraseFiles) {
llvm::sys::fs::remove(OF.TempFilename); llvm::sys::fs::remove(OF.TempFilename);
@ -570,13 +566,12 @@ void CompilerInstance::clearOutputFiles(bool EraseFiles) {
} }
} else if (!OF.Filename.empty() && EraseFiles) } else if (!OF.Filename.empty() && EraseFiles)
llvm::sys::fs::remove(OF.Filename); llvm::sys::fs::remove(OF.Filename);
} }
OutputFiles.clear(); OutputFiles.clear();
NonSeekStream.reset(); NonSeekStream.reset();
} }
raw_pwrite_stream * std::unique_ptr<raw_pwrite_stream>
CompilerInstance::createDefaultOutputFile(bool Binary, StringRef InFile, CompilerInstance::createDefaultOutputFile(bool Binary, StringRef InFile,
StringRef Extension) { StringRef Extension) {
return createOutputFile(getFrontendOpts().OutputFile, Binary, return createOutputFile(getFrontendOpts().OutputFile, Binary,
@ -584,14 +579,11 @@ CompilerInstance::createDefaultOutputFile(bool Binary, StringRef InFile,
/*UseTemporary=*/true); /*UseTemporary=*/true);
} }
llvm::raw_null_ostream *CompilerInstance::createNullOutputFile() { std::unique_ptr<raw_pwrite_stream> CompilerInstance::createNullOutputFile() {
auto OS = llvm::make_unique<llvm::raw_null_ostream>(); return llvm::make_unique<llvm::raw_null_ostream>();
llvm::raw_null_ostream *Ret = OS.get();
addOutputFile(OutputFile("", "", std::move(OS)));
return Ret;
} }
raw_pwrite_stream * std::unique_ptr<raw_pwrite_stream>
CompilerInstance::createOutputFile(StringRef OutputPath, bool Binary, CompilerInstance::createOutputFile(StringRef OutputPath, bool Binary,
bool RemoveFileOnSignal, StringRef InFile, bool RemoveFileOnSignal, StringRef InFile,
StringRef Extension, bool UseTemporary, StringRef Extension, bool UseTemporary,
@ -607,13 +599,12 @@ CompilerInstance::createOutputFile(StringRef OutputPath, bool Binary,
return nullptr; return nullptr;
} }
raw_pwrite_stream *Ret = OS.get();
// Add the output file -- but don't try to remove "-", since this means we are // Add the output file -- but don't try to remove "-", since this means we are
// using stdin. // using stdin.
addOutputFile(OutputFile((OutputPathName != "-") ? OutputPathName : "", addOutputFile(
TempPathName, std::move(OS))); OutputFile((OutputPathName != "-") ? OutputPathName : "", TempPathName));
return Ret; return OS;
} }
std::unique_ptr<llvm::raw_pwrite_stream> CompilerInstance::createOutputFile( std::unique_ptr<llvm::raw_pwrite_stream> CompilerInstance::createOutputFile(

View File

@ -48,8 +48,9 @@ void InitOnlyAction::ExecuteAction() {
std::unique_ptr<ASTConsumer> std::unique_ptr<ASTConsumer>
ASTPrintAction::CreateASTConsumer(CompilerInstance &CI, StringRef InFile) { ASTPrintAction::CreateASTConsumer(CompilerInstance &CI, StringRef InFile) {
if (raw_ostream *OS = CI.createDefaultOutputFile(false, InFile)) if (std::unique_ptr<raw_ostream> OS =
return CreateASTPrinter(OS, CI.getFrontendOpts().ASTDumpFilter); CI.createDefaultOutputFile(false, InFile))
return CreateASTPrinter(std::move(OS), CI.getFrontendOpts().ASTDumpFilter);
return nullptr; return nullptr;
} }
@ -80,7 +81,7 @@ std::unique_ptr<ASTConsumer>
GeneratePCHAction::CreateASTConsumer(CompilerInstance &CI, StringRef InFile) { GeneratePCHAction::CreateASTConsumer(CompilerInstance &CI, StringRef InFile) {
std::string Sysroot; std::string Sysroot;
std::string OutputFile; std::string OutputFile;
raw_pwrite_stream *OS = std::unique_ptr<raw_pwrite_stream> OS =
ComputeASTConsumerArguments(CI, InFile, Sysroot, OutputFile); ComputeASTConsumerArguments(CI, InFile, Sysroot, OutputFile);
if (!OS) if (!OS)
return nullptr; return nullptr;
@ -97,13 +98,15 @@ GeneratePCHAction::CreateASTConsumer(CompilerInstance &CI, StringRef InFile) {
/*IncludeTimestamps*/ /*IncludeTimestamps*/
+CI.getFrontendOpts().IncludeTimestamps)); +CI.getFrontendOpts().IncludeTimestamps));
Consumers.push_back(CI.getPCHContainerWriter().CreatePCHContainerGenerator( Consumers.push_back(CI.getPCHContainerWriter().CreatePCHContainerGenerator(
CI, InFile, OutputFile, OS, Buffer)); CI, InFile, OutputFile, std::move(OS), Buffer));
return llvm::make_unique<MultiplexConsumer>(std::move(Consumers)); return llvm::make_unique<MultiplexConsumer>(std::move(Consumers));
} }
raw_pwrite_stream *GeneratePCHAction::ComputeASTConsumerArguments( std::unique_ptr<raw_pwrite_stream>
CompilerInstance &CI, StringRef InFile, std::string &Sysroot, GeneratePCHAction::ComputeASTConsumerArguments(CompilerInstance &CI,
StringRef InFile,
std::string &Sysroot,
std::string &OutputFile) { std::string &OutputFile) {
Sysroot = CI.getHeaderSearchOpts().Sysroot; Sysroot = CI.getHeaderSearchOpts().Sysroot;
if (CI.getFrontendOpts().RelocatablePCH && Sysroot.empty()) { if (CI.getFrontendOpts().RelocatablePCH && Sysroot.empty()) {
@ -114,7 +117,7 @@ raw_pwrite_stream *GeneratePCHAction::ComputeASTConsumerArguments(
// We use createOutputFile here because this is exposed via libclang, and we // We use createOutputFile here because this is exposed via libclang, and we
// must disable the RemoveFileOnSignal behavior. // must disable the RemoveFileOnSignal behavior.
// We use a temporary to avoid race conditions. // We use a temporary to avoid race conditions.
raw_pwrite_stream *OS = std::unique_ptr<raw_pwrite_stream> OS =
CI.createOutputFile(CI.getFrontendOpts().OutputFile, /*Binary=*/true, CI.createOutputFile(CI.getFrontendOpts().OutputFile, /*Binary=*/true,
/*RemoveFileOnSignal=*/false, InFile, /*RemoveFileOnSignal=*/false, InFile,
/*Extension=*/"", /*useTemporary=*/true); /*Extension=*/"", /*useTemporary=*/true);
@ -130,7 +133,7 @@ GenerateModuleAction::CreateASTConsumer(CompilerInstance &CI,
StringRef InFile) { StringRef InFile) {
std::string Sysroot; std::string Sysroot;
std::string OutputFile; std::string OutputFile;
raw_pwrite_stream *OS = std::unique_ptr<raw_pwrite_stream> OS =
ComputeASTConsumerArguments(CI, InFile, Sysroot, OutputFile); ComputeASTConsumerArguments(CI, InFile, Sysroot, OutputFile);
if (!OS) if (!OS)
return nullptr; return nullptr;
@ -145,7 +148,7 @@ GenerateModuleAction::CreateASTConsumer(CompilerInstance &CI,
/*IncludeTimestamps=*/ /*IncludeTimestamps=*/
+CI.getFrontendOpts().BuildingImplicitModule)); +CI.getFrontendOpts().BuildingImplicitModule));
Consumers.push_back(CI.getPCHContainerWriter().CreatePCHContainerGenerator( Consumers.push_back(CI.getPCHContainerWriter().CreatePCHContainerGenerator(
CI, InFile, OutputFile, OS, Buffer)); CI, InFile, OutputFile, std::move(OS), Buffer));
return llvm::make_unique<MultiplexConsumer>(std::move(Consumers)); return llvm::make_unique<MultiplexConsumer>(std::move(Consumers));
} }
@ -378,8 +381,10 @@ bool GenerateModuleAction::BeginSourceFileAction(CompilerInstance &CI,
return true; return true;
} }
raw_pwrite_stream *GenerateModuleAction::ComputeASTConsumerArguments( std::unique_ptr<raw_pwrite_stream>
CompilerInstance &CI, StringRef InFile, std::string &Sysroot, GenerateModuleAction::ComputeASTConsumerArguments(CompilerInstance &CI,
StringRef InFile,
std::string &Sysroot,
std::string &OutputFile) { std::string &OutputFile) {
// If no output file was provided, figure out where this module would go // If no output file was provided, figure out where this module would go
// in the module cache. // in the module cache.
@ -393,7 +398,7 @@ raw_pwrite_stream *GenerateModuleAction::ComputeASTConsumerArguments(
// We use createOutputFile here because this is exposed via libclang, and we // We use createOutputFile here because this is exposed via libclang, and we
// must disable the RemoveFileOnSignal behavior. // must disable the RemoveFileOnSignal behavior.
// We use a temporary to avoid race conditions. // We use a temporary to avoid race conditions.
raw_pwrite_stream *OS = std::unique_ptr<raw_pwrite_stream> OS =
CI.createOutputFile(CI.getFrontendOpts().OutputFile, /*Binary=*/true, CI.createOutputFile(CI.getFrontendOpts().OutputFile, /*Binary=*/true,
/*RemoveFileOnSignal=*/false, InFile, /*RemoveFileOnSignal=*/false, InFile,
/*Extension=*/"", /*useTemporary=*/true, /*Extension=*/"", /*useTemporary=*/true,
@ -647,11 +652,12 @@ void DumpTokensAction::ExecuteAction() {
void GeneratePTHAction::ExecuteAction() { void GeneratePTHAction::ExecuteAction() {
CompilerInstance &CI = getCompilerInstance(); CompilerInstance &CI = getCompilerInstance();
raw_pwrite_stream *OS = CI.createDefaultOutputFile(true, getCurrentFile()); std::unique_ptr<raw_pwrite_stream> OS =
CI.createDefaultOutputFile(true, getCurrentFile());
if (!OS) if (!OS)
return; return;
CacheTokens(CI.getPreprocessor(), OS); CacheTokens(CI.getPreprocessor(), OS.get());
} }
void PreprocessOnlyAction::ExecuteAction() { void PreprocessOnlyAction::ExecuteAction() {
@ -712,10 +718,11 @@ void PrintPreprocessedAction::ExecuteAction() {
} }
} }
raw_ostream *OS = CI.createDefaultOutputFile(BinaryMode, getCurrentFile()); std::unique_ptr<raw_ostream> OS =
CI.createDefaultOutputFile(BinaryMode, getCurrentFile());
if (!OS) return; if (!OS) return;
DoPrintPreprocessedInput(CI.getPreprocessor(), OS, DoPrintPreprocessedInput(CI.getPreprocessor(), OS.get(),
CI.getPreprocessorOutputOpts()); CI.getPreprocessorOutputOpts());
} }

View File

@ -28,12 +28,12 @@ namespace {
/// \brief A PCHContainerGenerator that writes out the PCH to a flat file. /// \brief A PCHContainerGenerator that writes out the PCH to a flat file.
class RawPCHContainerGenerator : public ASTConsumer { class RawPCHContainerGenerator : public ASTConsumer {
std::shared_ptr<PCHBuffer> Buffer; std::shared_ptr<PCHBuffer> Buffer;
raw_pwrite_stream *OS; std::unique_ptr<raw_pwrite_stream> OS;
public: public:
RawPCHContainerGenerator(llvm::raw_pwrite_stream *OS, RawPCHContainerGenerator(std::unique_ptr<llvm::raw_pwrite_stream> OS,
std::shared_ptr<PCHBuffer> Buffer) std::shared_ptr<PCHBuffer> Buffer)
: Buffer(std::move(Buffer)), OS(OS) {} : Buffer(std::move(Buffer)), OS(std::move(OS)) {}
~RawPCHContainerGenerator() override = default; ~RawPCHContainerGenerator() override = default;
@ -53,9 +53,9 @@ public:
std::unique_ptr<ASTConsumer> RawPCHContainerWriter::CreatePCHContainerGenerator( std::unique_ptr<ASTConsumer> RawPCHContainerWriter::CreatePCHContainerGenerator(
CompilerInstance &CI, const std::string &MainFileName, CompilerInstance &CI, const std::string &MainFileName,
const std::string &OutputFileName, llvm::raw_pwrite_stream *OS, const std::string &OutputFileName, std::unique_ptr<llvm::raw_pwrite_stream> OS,
std::shared_ptr<PCHBuffer> Buffer) const { std::shared_ptr<PCHBuffer> Buffer) const {
return llvm::make_unique<RawPCHContainerGenerator>(OS, Buffer); return llvm::make_unique<RawPCHContainerGenerator>(std::move(OS), Buffer);
} }
void RawPCHContainerReader::ExtractPCH( void RawPCHContainerReader::ExtractPCH(

View File

@ -33,8 +33,9 @@ using namespace clang;
std::unique_ptr<ASTConsumer> std::unique_ptr<ASTConsumer>
HTMLPrintAction::CreateASTConsumer(CompilerInstance &CI, StringRef InFile) { HTMLPrintAction::CreateASTConsumer(CompilerInstance &CI, StringRef InFile) {
if (raw_ostream *OS = CI.createDefaultOutputFile(false, InFile)) if (std::unique_ptr<raw_ostream> OS =
return CreateHTMLPrinter(OS, CI.getPreprocessor()); CI.createDefaultOutputFile(false, InFile))
return CreateHTMLPrinter(std::move(OS), CI.getPreprocessor());
return nullptr; return nullptr;
} }
@ -152,14 +153,15 @@ bool FixItRecompile::BeginInvocation(CompilerInstance &CI) {
std::unique_ptr<ASTConsumer> std::unique_ptr<ASTConsumer>
RewriteObjCAction::CreateASTConsumer(CompilerInstance &CI, StringRef InFile) { RewriteObjCAction::CreateASTConsumer(CompilerInstance &CI, StringRef InFile) {
if (raw_ostream *OS = CI.createDefaultOutputFile(false, InFile, "cpp")) { if (std::unique_ptr<raw_ostream> OS =
CI.createDefaultOutputFile(false, InFile, "cpp")) {
if (CI.getLangOpts().ObjCRuntime.isNonFragile()) if (CI.getLangOpts().ObjCRuntime.isNonFragile())
return CreateModernObjCRewriter( return CreateModernObjCRewriter(
InFile, OS, CI.getDiagnostics(), CI.getLangOpts(), InFile, std::move(OS), CI.getDiagnostics(), CI.getLangOpts(),
CI.getDiagnosticOpts().NoRewriteMacros, CI.getDiagnosticOpts().NoRewriteMacros,
(CI.getCodeGenOpts().getDebugInfo() != codegenoptions::NoDebugInfo)); (CI.getCodeGenOpts().getDebugInfo() != codegenoptions::NoDebugInfo));
return CreateObjCRewriter(InFile, OS, return CreateObjCRewriter(InFile, std::move(OS), CI.getDiagnostics(),
CI.getDiagnostics(), CI.getLangOpts(), CI.getLangOpts(),
CI.getDiagnosticOpts().NoRewriteMacros); CI.getDiagnosticOpts().NoRewriteMacros);
} }
return nullptr; return nullptr;
@ -173,25 +175,28 @@ RewriteObjCAction::CreateASTConsumer(CompilerInstance &CI, StringRef InFile) {
void RewriteMacrosAction::ExecuteAction() { void RewriteMacrosAction::ExecuteAction() {
CompilerInstance &CI = getCompilerInstance(); CompilerInstance &CI = getCompilerInstance();
raw_ostream *OS = CI.createDefaultOutputFile(true, getCurrentFile()); std::unique_ptr<raw_ostream> OS =
CI.createDefaultOutputFile(true, getCurrentFile());
if (!OS) return; if (!OS) return;
RewriteMacrosInInput(CI.getPreprocessor(), OS); RewriteMacrosInInput(CI.getPreprocessor(), OS.get());
} }
void RewriteTestAction::ExecuteAction() { void RewriteTestAction::ExecuteAction() {
CompilerInstance &CI = getCompilerInstance(); CompilerInstance &CI = getCompilerInstance();
raw_ostream *OS = CI.createDefaultOutputFile(false, getCurrentFile()); std::unique_ptr<raw_ostream> OS =
CI.createDefaultOutputFile(false, getCurrentFile());
if (!OS) return; if (!OS) return;
DoRewriteTest(CI.getPreprocessor(), OS); DoRewriteTest(CI.getPreprocessor(), OS.get());
} }
void RewriteIncludesAction::ExecuteAction() { void RewriteIncludesAction::ExecuteAction() {
CompilerInstance &CI = getCompilerInstance(); CompilerInstance &CI = getCompilerInstance();
raw_ostream *OS = CI.createDefaultOutputFile(true, getCurrentFile()); std::unique_ptr<raw_ostream> OS =
CI.createDefaultOutputFile(true, getCurrentFile());
if (!OS) return; if (!OS) return;
RewriteIncludesInInput(CI.getPreprocessor(), OS, RewriteIncludesInInput(CI.getPreprocessor(), OS.get(),
CI.getPreprocessorOutputOpts()); CI.getPreprocessorOutputOpts());
} }

View File

@ -32,14 +32,14 @@ using namespace clang;
namespace { namespace {
class HTMLPrinter : public ASTConsumer { class HTMLPrinter : public ASTConsumer {
Rewriter R; Rewriter R;
raw_ostream *Out; std::unique_ptr<raw_ostream> Out;
Preprocessor &PP; Preprocessor &PP;
bool SyntaxHighlight, HighlightMacros; bool SyntaxHighlight, HighlightMacros;
public: public:
HTMLPrinter(raw_ostream *OS, Preprocessor &pp, HTMLPrinter(std::unique_ptr<raw_ostream> OS, Preprocessor &pp,
bool _SyntaxHighlight, bool _HighlightMacros) bool _SyntaxHighlight, bool _HighlightMacros)
: Out(OS), PP(pp), SyntaxHighlight(_SyntaxHighlight), : Out(std::move(OS)), PP(pp), SyntaxHighlight(_SyntaxHighlight),
HighlightMacros(_HighlightMacros) {} HighlightMacros(_HighlightMacros) {}
void Initialize(ASTContext &context) override; void Initialize(ASTContext &context) override;
@ -47,11 +47,10 @@ namespace {
}; };
} }
std::unique_ptr<ASTConsumer> clang::CreateHTMLPrinter(raw_ostream *OS, std::unique_ptr<ASTConsumer>
Preprocessor &PP, clang::CreateHTMLPrinter(std::unique_ptr<raw_ostream> OS, Preprocessor &PP,
bool SyntaxHighlight, bool SyntaxHighlight, bool HighlightMacros) {
bool HighlightMacros) { return llvm::make_unique<HTMLPrinter>(std::move(OS), PP, SyntaxHighlight,
return llvm::make_unique<HTMLPrinter>(OS, PP, SyntaxHighlight,
HighlightMacros); HighlightMacros);
} }

View File

@ -72,7 +72,7 @@ namespace {
Stmt *CurrentBody; Stmt *CurrentBody;
ParentMap *PropParentMap; // created lazily. ParentMap *PropParentMap; // created lazily.
std::string InFileName; std::string InFileName;
raw_ostream* OutFile; std::unique_ptr<raw_ostream> OutFile;
std::string Preamble; std::string Preamble;
TypeDecl *ProtocolTypeDecl; TypeDecl *ProtocolTypeDecl;
@ -239,7 +239,7 @@ namespace {
void HandleTopLevelSingleDecl(Decl *D); void HandleTopLevelSingleDecl(Decl *D);
void HandleDeclInMainFile(Decl *D); void HandleDeclInMainFile(Decl *D);
RewriteModernObjC(std::string inFile, raw_ostream *OS, RewriteModernObjC(std::string inFile, std::unique_ptr<raw_ostream> OS,
DiagnosticsEngine &D, const LangOptions &LOpts, DiagnosticsEngine &D, const LangOptions &LOpts,
bool silenceMacroWarn, bool LineInfo); bool silenceMacroWarn, bool LineInfo);
@ -638,11 +638,12 @@ static bool IsHeaderFile(const std::string &Filename) {
return Ext == "h" || Ext == "hh" || Ext == "H"; return Ext == "h" || Ext == "hh" || Ext == "H";
} }
RewriteModernObjC::RewriteModernObjC(std::string inFile, raw_ostream* OS, RewriteModernObjC::RewriteModernObjC(std::string inFile,
DiagnosticsEngine &D, const LangOptions &LOpts, std::unique_ptr<raw_ostream> OS,
bool silenceMacroWarn, DiagnosticsEngine &D,
bool LineInfo) const LangOptions &LOpts,
: Diags(D), LangOpts(LOpts), InFileName(inFile), OutFile(OS), bool silenceMacroWarn, bool LineInfo)
: Diags(D), LangOpts(LOpts), InFileName(inFile), OutFile(std::move(OS)),
SilenceRewriteMacroWarning(silenceMacroWarn), GenerateLineInfo(LineInfo) { SilenceRewriteMacroWarning(silenceMacroWarn), GenerateLineInfo(LineInfo) {
IsHeader = IsHeaderFile(inFile); IsHeader = IsHeaderFile(inFile);
RewriteFailedDiag = Diags.getCustomDiagID(DiagnosticsEngine::Warning, RewriteFailedDiag = Diags.getCustomDiagID(DiagnosticsEngine::Warning,
@ -659,10 +660,12 @@ RewriteModernObjC::RewriteModernObjC(std::string inFile, raw_ostream* OS,
} }
std::unique_ptr<ASTConsumer> clang::CreateModernObjCRewriter( std::unique_ptr<ASTConsumer> clang::CreateModernObjCRewriter(
const std::string &InFile, raw_ostream *OS, DiagnosticsEngine &Diags, const std::string &InFile, std::unique_ptr<raw_ostream> OS,
const LangOptions &LOpts, bool SilenceRewriteMacroWarning, bool LineInfo) { DiagnosticsEngine &Diags, const LangOptions &LOpts,
return llvm::make_unique<RewriteModernObjC>( bool SilenceRewriteMacroWarning, bool LineInfo) {
InFile, OS, Diags, LOpts, SilenceRewriteMacroWarning, LineInfo); return llvm::make_unique<RewriteModernObjC>(InFile, std::move(OS), Diags,
LOpts, SilenceRewriteMacroWarning,
LineInfo);
} }
void RewriteModernObjC::InitializeCommon(ASTContext &context) { void RewriteModernObjC::InitializeCommon(ASTContext &context) {

View File

@ -71,7 +71,7 @@ namespace {
Stmt *CurrentBody; Stmt *CurrentBody;
ParentMap *PropParentMap; // created lazily. ParentMap *PropParentMap; // created lazily.
std::string InFileName; std::string InFileName;
raw_ostream* OutFile; std::unique_ptr<raw_ostream> OutFile;
std::string Preamble; std::string Preamble;
TypeDecl *ProtocolTypeDecl; TypeDecl *ProtocolTypeDecl;
@ -190,7 +190,7 @@ namespace {
void HandleTopLevelSingleDecl(Decl *D); void HandleTopLevelSingleDecl(Decl *D);
void HandleDeclInMainFile(Decl *D); void HandleDeclInMainFile(Decl *D);
RewriteObjC(std::string inFile, raw_ostream *OS, RewriteObjC(std::string inFile, std::unique_ptr<raw_ostream> OS,
DiagnosticsEngine &D, const LangOptions &LOpts, DiagnosticsEngine &D, const LangOptions &LOpts,
bool silenceMacroWarn); bool silenceMacroWarn);
@ -506,11 +506,10 @@ namespace {
class RewriteObjCFragileABI : public RewriteObjC { class RewriteObjCFragileABI : public RewriteObjC {
public: public:
RewriteObjCFragileABI(std::string inFile, raw_ostream *OS, RewriteObjCFragileABI(std::string inFile, std::unique_ptr<raw_ostream> OS,
DiagnosticsEngine &D, const LangOptions &LOpts, DiagnosticsEngine &D, const LangOptions &LOpts,
bool silenceMacroWarn) : RewriteObjC(inFile, OS, bool silenceMacroWarn)
D, LOpts, : RewriteObjC(inFile, std::move(OS), D, LOpts, silenceMacroWarn) {}
silenceMacroWarn) {}
~RewriteObjCFragileABI() override {} ~RewriteObjCFragileABI() override {}
void Initialize(ASTContext &context) override; void Initialize(ASTContext &context) override;
@ -575,10 +574,10 @@ static bool IsHeaderFile(const std::string &Filename) {
return Ext == "h" || Ext == "hh" || Ext == "H"; return Ext == "h" || Ext == "hh" || Ext == "H";
} }
RewriteObjC::RewriteObjC(std::string inFile, raw_ostream* OS, RewriteObjC::RewriteObjC(std::string inFile, std::unique_ptr<raw_ostream> OS,
DiagnosticsEngine &D, const LangOptions &LOpts, DiagnosticsEngine &D, const LangOptions &LOpts,
bool silenceMacroWarn) bool silenceMacroWarn)
: Diags(D), LangOpts(LOpts), InFileName(inFile), OutFile(OS), : Diags(D), LangOpts(LOpts), InFileName(inFile), OutFile(std::move(OS)),
SilenceRewriteMacroWarning(silenceMacroWarn) { SilenceRewriteMacroWarning(silenceMacroWarn) {
IsHeader = IsHeaderFile(inFile); IsHeader = IsHeaderFile(inFile);
RewriteFailedDiag = Diags.getCustomDiagID(DiagnosticsEngine::Warning, RewriteFailedDiag = Diags.getCustomDiagID(DiagnosticsEngine::Warning,
@ -590,11 +589,12 @@ RewriteObjC::RewriteObjC(std::string inFile, raw_ostream* OS,
} }
std::unique_ptr<ASTConsumer> std::unique_ptr<ASTConsumer>
clang::CreateObjCRewriter(const std::string &InFile, raw_ostream *OS, clang::CreateObjCRewriter(const std::string &InFile,
std::unique_ptr<raw_ostream> OS,
DiagnosticsEngine &Diags, const LangOptions &LOpts, DiagnosticsEngine &Diags, const LangOptions &LOpts,
bool SilenceRewriteMacroWarning) { bool SilenceRewriteMacroWarning) {
return llvm::make_unique<RewriteObjCFragileABI>(InFile, OS, Diags, LOpts, return llvm::make_unique<RewriteObjCFragileABI>(
SilenceRewriteMacroWarning); InFile, std::move(OS), Diags, LOpts, SilenceRewriteMacroWarning);
} }
void RewriteObjC::InitializeCommon(ASTContext &context) { void RewriteObjC::InitializeCommon(ASTContext &context) {

View File

@ -142,7 +142,7 @@ public:
return clang::CreateASTDumper(ASTDumpFilter, /*DumpDecls=*/true, return clang::CreateASTDumper(ASTDumpFilter, /*DumpDecls=*/true,
/*DumpLookups=*/false); /*DumpLookups=*/false);
if (ASTPrint) if (ASTPrint)
return clang::CreateASTPrinter(&llvm::outs(), ASTDumpFilter); return clang::CreateASTPrinter(nullptr, ASTDumpFilter);
return llvm::make_unique<clang::ASTConsumer>(); return llvm::make_unique<clang::ASTConsumer>();
} }
}; };