diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2015-01-18 16:23:48 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2015-01-18 16:23:48 +0000 |
commit | 06d4ba388873e6d1cfa9cd715a8935ecc8cd2097 (patch) | |
tree | 3eb853da77d46cc77c4b017525a422f9ddb1385b /lib/CodeGen/CodeGenAction.cpp | |
parent | 30d791273d07fac9c0c1641a0731191bca6e8606 (diff) | |
download | src-06d4ba388873e6d1cfa9cd715a8935ecc8cd2097.tar.gz src-06d4ba388873e6d1cfa9cd715a8935ecc8cd2097.zip |
Notes
Diffstat (limited to 'lib/CodeGen/CodeGenAction.cpp')
-rw-r--r-- | lib/CodeGen/CodeGenAction.cpp | 89 |
1 files changed, 57 insertions, 32 deletions
diff --git a/lib/CodeGen/CodeGenAction.cpp b/lib/CodeGen/CodeGenAction.cpp index 04d2cd9d53e4..a6f6fdef335c 100644 --- a/lib/CodeGen/CodeGenAction.cpp +++ b/lib/CodeGen/CodeGenAction.cpp @@ -7,18 +7,20 @@ // //===----------------------------------------------------------------------===// -#include "clang/CodeGen/CodeGenAction.h" +#include "CoverageMappingGen.h" #include "clang/AST/ASTConsumer.h" #include "clang/AST/ASTContext.h" -#include "clang/AST/DeclGroup.h" #include "clang/AST/DeclCXX.h" +#include "clang/AST/DeclGroup.h" #include "clang/Basic/FileManager.h" #include "clang/Basic/SourceManager.h" #include "clang/Basic/TargetInfo.h" #include "clang/CodeGen/BackendUtil.h" +#include "clang/CodeGen/CodeGenAction.h" #include "clang/CodeGen/ModuleBuilder.h" #include "clang/Frontend/CompilerInstance.h" #include "clang/Frontend/FrontendDiagnostic.h" +#include "clang/Lex/Preprocessor.h" #include "llvm/ADT/SmallString.h" #include "llvm/Bitcode/ReaderWriter.h" #include "llvm/IR/DebugInfo.h" @@ -59,16 +61,18 @@ namespace clang { const TargetOptions &targetopts, const LangOptions &langopts, bool TimePasses, const std::string &infile, llvm::Module *LinkModule, - raw_ostream *OS, LLVMContext &C) + raw_ostream *OS, LLVMContext &C, + CoverageSourceInfo *CoverageInfo = nullptr) : Diags(_Diags), Action(action), CodeGenOpts(compopts), TargetOpts(targetopts), LangOpts(langopts), AsmOutStream(OS), - Context(), LLVMIRGeneration("LLVM IR Generation Time"), - Gen(CreateLLVMCodeGen(Diags, infile, compopts, targetopts, C)), + Context(nullptr), LLVMIRGeneration("LLVM IR Generation Time"), + Gen(CreateLLVMCodeGen(Diags, infile, compopts, + targetopts, C, CoverageInfo)), LinkModule(LinkModule) { llvm::TimePassesIsEnabled = TimePasses; } - llvm::Module *takeModule() { return TheModule.release(); } + std::unique_ptr<llvm::Module> takeModule() { return std::move(TheModule); } llvm::Module *takeLinkModule() { return LinkModule.release(); } void HandleCXXStaticMemberVarInstantiation(VarDecl *VD) override { @@ -149,13 +153,10 @@ namespace clang { // Link LinkModule into this module if present, preserving its validity. if (LinkModule) { - std::string ErrorMsg; - if (Linker::LinkModules(M, LinkModule.get(), Linker::PreserveSource, - &ErrorMsg)) { - Diags.Report(diag::err_fe_cannot_link_module) - << LinkModule->getModuleIdentifier() << ErrorMsg; + if (Linker::LinkModules( + M, LinkModule.get(), + [=](const DiagnosticInfo &DI) { linkerDiagnosticHandler(DI); })) return; - } } // Install an inline asm handler so that diagnostics get printed through @@ -218,6 +219,8 @@ namespace clang { ((BackendConsumer*)Context)->InlineAsmDiagHandler2(SM, Loc); } + void linkerDiagnosticHandler(const llvm::DiagnosticInfo &DI); + static void DiagnosticHandler(const llvm::DiagnosticInfo &DI, void *Context) { ((BackendConsumer *)Context)->DiagnosticHandlerImpl(DI); @@ -269,11 +272,11 @@ static FullSourceLoc ConvertBackendLocation(const llvm::SMDiagnostic &D, // Create the copy and transfer ownership to clang::SourceManager. // TODO: Avoid copying files into memory. - llvm::MemoryBuffer *CBuf = - llvm::MemoryBuffer::getMemBufferCopy(LBuf->getBuffer(), - LBuf->getBufferIdentifier()); + std::unique_ptr<llvm::MemoryBuffer> CBuf = + llvm::MemoryBuffer::getMemBufferCopy(LBuf->getBuffer(), + LBuf->getBufferIdentifier()); // FIXME: Keep a file ID map instead of creating new IDs for each location. - FileID FID = CSM.createFileID(CBuf); + FileID FID = CSM.createFileID(std::move(CBuf)); // Translate the offset into the file. unsigned Offset = D.getLoc().getPointer() - LBuf->getBufferStart(); @@ -493,6 +496,21 @@ void BackendConsumer::OptimizationFailureHandler( EmitOptimizationMessage(D, diag::warn_fe_backend_optimization_failure); } +void BackendConsumer::linkerDiagnosticHandler(const DiagnosticInfo &DI) { + if (DI.getSeverity() != DS_Error) + return; + + std::string MsgStorage; + { + raw_string_ostream Stream(MsgStorage); + DiagnosticPrinterRawOStream DP(Stream); + DI.print(DP); + } + + Diags.Report(diag::err_fe_cannot_link_module) + << LinkModule->getModuleIdentifier() << MsgStorage; +} + /// \brief This function is invoked when the backend needs /// to report something to the user. void BackendConsumer::DiagnosticHandlerImpl(const DiagnosticInfo &DI) { @@ -572,10 +590,12 @@ void CodeGenAction::EndSourceFileAction() { BEConsumer->takeLinkModule(); // Steal the module from the consumer. - TheModule.reset(BEConsumer->takeModule()); + TheModule = BEConsumer->takeModule(); } -llvm::Module *CodeGenAction::takeModule() { return TheModule.release(); } +std::unique_ptr<llvm::Module> CodeGenAction::takeModule() { + return std::move(TheModule); +} llvm::LLVMContext *CodeGenAction::takeLLVMContext() { OwnsVMContext = false; @@ -603,8 +623,8 @@ static raw_ostream *GetOutputStream(CompilerInstance &CI, llvm_unreachable("Invalid action!"); } -ASTConsumer *CodeGenAction::CreateASTConsumer(CompilerInstance &CI, - StringRef InFile) { +std::unique_ptr<ASTConsumer> +CodeGenAction::CreateASTConsumer(CompilerInstance &CI, StringRef InFile) { BackendAction BA = static_cast<BackendAction>(Act); std::unique_ptr<raw_ostream> OS(GetOutputStream(CI, InFile, BA)); if (BA != Backend_EmitNothing && !OS) @@ -616,18 +636,15 @@ ASTConsumer *CodeGenAction::CreateASTConsumer(CompilerInstance &CI, // loaded from bitcode, do so now. const std::string &LinkBCFile = CI.getCodeGenOpts().LinkBitcodeFile; if (!LinkModuleToUse && !LinkBCFile.empty()) { - std::string ErrorStr; - - llvm::MemoryBuffer *BCBuf = - CI.getFileManager().getBufferForFile(LinkBCFile, &ErrorStr); + auto BCBuf = CI.getFileManager().getBufferForFile(LinkBCFile); if (!BCBuf) { CI.getDiagnostics().Report(diag::err_cannot_open_file) - << LinkBCFile << ErrorStr; + << LinkBCFile << BCBuf.getError().message(); return nullptr; } ErrorOr<llvm::Module *> ModuleOrErr = - getLazyBitcodeModule(BCBuf, *VMContext); + getLazyBitcodeModule(std::move(*BCBuf), *VMContext); if (std::error_code EC = ModuleOrErr.getError()) { CI.getDiagnostics().Report(diag::err_cannot_open_file) << LinkBCFile << EC.message(); @@ -636,11 +653,19 @@ ASTConsumer *CodeGenAction::CreateASTConsumer(CompilerInstance &CI, LinkModuleToUse = ModuleOrErr.get(); } - BEConsumer = new BackendConsumer(BA, CI.getDiagnostics(), CI.getCodeGenOpts(), - CI.getTargetOpts(), CI.getLangOpts(), - CI.getFrontendOpts().ShowTimers, InFile, - LinkModuleToUse, OS.release(), *VMContext); - return BEConsumer; + CoverageSourceInfo *CoverageInfo = nullptr; + // Add the preprocessor callback only when the coverage mapping is generated. + if (CI.getCodeGenOpts().CoverageMapping) { + CoverageInfo = new CoverageSourceInfo; + CI.getPreprocessor().addPPCallbacks( + std::unique_ptr<PPCallbacks>(CoverageInfo)); + } + std::unique_ptr<BackendConsumer> Result(new BackendConsumer( + BA, CI.getDiagnostics(), CI.getCodeGenOpts(), CI.getTargetOpts(), + CI.getLangOpts(), CI.getFrontendOpts().ShowTimers, InFile, + LinkModuleToUse, OS.release(), *VMContext, CoverageInfo)); + BEConsumer = Result.get(); + return std::move(Result); } void CodeGenAction::ExecuteAction() { @@ -660,7 +685,7 @@ void CodeGenAction::ExecuteAction() { return; llvm::SMDiagnostic Err; - TheModule.reset(ParseIR(MainFile, Err, *VMContext)); + TheModule = parseIR(MainFile->getMemBufferRef(), Err, *VMContext); if (!TheModule) { // Translate from the diagnostic info to the SourceManager location if // available. |