forked from OSchip/llvm-project
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:
parent
38c5318662
commit
03f8907f65
|
@ -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);
|
||||||
|
|
|
@ -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;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
|
@ -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;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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.
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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(
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
|
@ -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(
|
||||||
|
|
|
@ -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());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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(
|
||||||
|
|
|
@ -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());
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
|
@ -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>();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in New Issue