diff options
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 04d2cd9d53e45..a6f6fdef335c9 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.  | 
