diff options
| author | Dimitry Andric <dim@FreeBSD.org> | 2016-08-16 21:17:51 +0000 | 
|---|---|---|
| committer | Dimitry Andric <dim@FreeBSD.org> | 2016-08-16 21:17:51 +0000 | 
| commit | e7145dcb9f6563389ebbfa0572ef7589bdd94b1b (patch) | |
| tree | b1b30c4998f6e9769784be87d402e4f8db13e34d /contrib/llvm/tools/clang/lib/CodeGen/CodeGenAction.cpp | |
| parent | 3ca95b020283db6244cab92ede73c969253b6a31 (diff) | |
| parent | 7fd6ba58d980ec2bf312a80444948501dd27d020 (diff) | |
Notes
Diffstat (limited to 'contrib/llvm/tools/clang/lib/CodeGen/CodeGenAction.cpp')
| -rw-r--r-- | contrib/llvm/tools/clang/lib/CodeGen/CodeGenAction.cpp | 190 | 
1 files changed, 126 insertions, 64 deletions
diff --git a/contrib/llvm/tools/clang/lib/CodeGen/CodeGenAction.cpp b/contrib/llvm/tools/clang/lib/CodeGen/CodeGenAction.cpp index 0a670ab19aa5..49738a20f493 100644 --- a/contrib/llvm/tools/clang/lib/CodeGen/CodeGenAction.cpp +++ b/contrib/llvm/tools/clang/lib/CodeGen/CodeGenAction.cpp @@ -46,14 +46,13 @@ namespace clang {      const CodeGenOptions &CodeGenOpts;      const TargetOptions &TargetOpts;      const LangOptions &LangOpts; -    raw_pwrite_stream *AsmOutStream; +    std::unique_ptr<raw_pwrite_stream> AsmOutStream;      ASTContext *Context;      Timer LLVMIRGeneration;      std::unique_ptr<CodeGenerator> Gen; -    std::unique_ptr<llvm::Module> TheModule;      SmallVector<std::pair<unsigned, std::unique_ptr<llvm::Module>>, 4>          LinkModules; @@ -69,11 +68,12 @@ namespace clang {          const TargetOptions &TargetOpts, const LangOptions &LangOpts,          bool TimePasses, const std::string &InFile,          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)          : Diags(Diags), Action(Action), CodeGenOpts(CodeGenOpts), -          TargetOpts(TargetOpts), LangOpts(LangOpts), AsmOutStream(OS), -          Context(nullptr), LLVMIRGeneration("LLVM IR Generation Time"), +          TargetOpts(TargetOpts), LangOpts(LangOpts), +          AsmOutStream(std::move(OS)), Context(nullptr), +          LLVMIRGeneration("LLVM IR Generation Time"),            Gen(CreateLLVMCodeGen(Diags, InFile, HeaderSearchOpts, PPOpts,                                  CodeGenOpts, C, CoverageInfo)) {        llvm::TimePassesIsEnabled = TimePasses; @@ -81,7 +81,10 @@ namespace clang {          this->LinkModules.push_back(              std::make_pair(I.first, std::unique_ptr<llvm::Module>(I.second)));      } -    std::unique_ptr<llvm::Module> takeModule() { return std::move(TheModule); } +    llvm::Module *getModule() const { return Gen->GetModule(); } +    std::unique_ptr<llvm::Module> takeModule() { +      return std::unique_ptr<llvm::Module>(Gen->ReleaseModule()); +    }      void releaseLinkModules() {        for (auto &I : LinkModules)          I.second.release(); @@ -101,8 +104,6 @@ namespace clang {        Gen->Initialize(Ctx); -      TheModule.reset(Gen->GetModule()); -        if (llvm::TimePassesIsEnabled)          LLVMIRGeneration.stopTimer();      } @@ -123,14 +124,14 @@ namespace clang {        return true;      } -    void HandleInlineMethodDefinition(CXXMethodDecl *D) override { +    void HandleInlineFunctionDefinition(FunctionDecl *D) override {        PrettyStackTraceDecl CrashInfo(D, SourceLocation(),                                       Context->getSourceManager(), -                                     "LLVM IR generation of inline method"); +                                     "LLVM IR generation of inline function");        if (llvm::TimePassesIsEnabled)          LLVMIRGeneration.startTimer(); -      Gen->HandleInlineMethodDefinition(D); +      Gen->HandleInlineFunctionDefinition(D);        if (llvm::TimePassesIsEnabled)          LLVMIRGeneration.stopTimer(); @@ -149,25 +150,12 @@ namespace clang {        }        // Silently ignore if we weren't initialized for some reason. -      if (!TheModule) +      if (!getModule())          return; -      // Make sure IR generation is happy with the module. This is released by -      // the module provider. -      llvm::Module *M = Gen->ReleaseModule(); -      if (!M) { -        // The module has been released by IR gen on failures, do not double -        // free. -        TheModule.release(); -        return; -      } - -      assert(TheModule.get() == M && -             "Unexpected module change during IR generation"); -        // Install an inline asm handler so that diagnostics get printed through        // our diagnostics hooks. -      LLVMContext &Ctx = TheModule->getContext(); +      LLVMContext &Ctx = getModule()->getContext();        LLVMContext::InlineAsmDiagHandlerTy OldHandler =          Ctx.getInlineAsmDiagnosticHandler();        void *OldContext = Ctx.getInlineAsmDiagnosticContext(); @@ -182,13 +170,15 @@ namespace clang {        for (auto &I : LinkModules) {          unsigned LinkFlags = I.first;          CurLinkModule = I.second.get(); -        if (Linker::linkModules(*M, std::move(I.second), LinkFlags)) +        if (Linker::linkModules(*getModule(), std::move(I.second), LinkFlags))            return;        } +      EmbedBitcode(getModule(), CodeGenOpts, llvm::MemoryBufferRef()); +        EmitBackendOutput(Diags, CodeGenOpts, TargetOpts, LangOpts, -                        C.getTargetInfo().getDataLayoutString(), -                        TheModule.get(), Action, AsmOutStream); +                        C.getTargetInfo().getDataLayout(), +                        getModule(), Action, std::move(AsmOutStream));        Ctx.setInlineAsmDiagnosticHandler(OldHandler, OldContext); @@ -210,21 +200,12 @@ namespace clang {        Gen->CompleteTentativeDefinition(D);      } -    void HandleVTable(CXXRecordDecl *RD) override { -      Gen->HandleVTable(RD); -    } - -    void HandleLinkerOptionPragma(llvm::StringRef Opts) override { -      Gen->HandleLinkerOptionPragma(Opts); +    void AssignInheritanceModel(CXXRecordDecl *RD) override { +      Gen->AssignInheritanceModel(RD);      } -    void HandleDetectMismatch(llvm::StringRef Name, -                                      llvm::StringRef Value) override { -      Gen->HandleDetectMismatch(Name, Value); -    } - -    void HandleDependentLibrary(llvm::StringRef Opts) override { -      Gen->HandleDependentLibrary(Opts); +    void HandleVTable(CXXRecordDecl *RD) override { +      Gen->HandleVTable(RD);      }      static void InlineAsmDiagHandler(const llvm::SMDiagnostic &SM,void *Context, @@ -238,6 +219,13 @@ namespace clang {        ((BackendConsumer *)Context)->DiagnosticHandlerImpl(DI);      } +    /// Get the best possible source location to represent a diagnostic that +    /// may have associated debug info. +    const FullSourceLoc +    getBestLocationFromDebugLoc(const llvm::DiagnosticInfoWithDebugLocBase &D, +                                bool &BadDebugInfo, StringRef &Filename, +                                unsigned &Line, unsigned &Column) const; +      void InlineAsmDiagHandler2(const llvm::SMDiagnostic &,                                 SourceLocation LocCookie); @@ -250,6 +238,8 @@ namespace clang {      /// \return True if the diagnostic has been successfully reported, false      /// otherwise.      bool StackSizeDiagHandler(const llvm::DiagnosticInfoStackSize &D); +    /// \brief Specialized handler for unsupported backend feature diagnostic. +    void UnsupportedDiagHandler(const llvm::DiagnosticInfoUnsupported &D);      /// \brief Specialized handlers for optimization remarks.      /// Note that these handlers only accept remarks and they always handle      /// them. @@ -426,25 +416,21 @@ BackendConsumer::StackSizeDiagHandler(const llvm::DiagnosticInfoStackSize &D) {      return false;    if (const Decl *ND = Gen->GetDeclForMangledName(D.getFunction().getName())) { +    // FIXME: Shouldn't need to truncate to uint32_t      Diags.Report(ND->getASTContext().getFullLoc(ND->getLocation()),                   diag::warn_fe_frame_larger_than) -        << D.getStackSize() << Decl::castToDeclContext(ND); +      << static_cast<uint32_t>(D.getStackSize()) << Decl::castToDeclContext(ND);      return true;    }    return false;  } -void BackendConsumer::EmitOptimizationMessage( -    const llvm::DiagnosticInfoOptimizationBase &D, unsigned DiagID) { -  // We only support warnings and remarks. -  assert(D.getSeverity() == llvm::DS_Remark || -         D.getSeverity() == llvm::DS_Warning); - +const FullSourceLoc BackendConsumer::getBestLocationFromDebugLoc( +    const llvm::DiagnosticInfoWithDebugLocBase &D, bool &BadDebugInfo, StringRef &Filename, +                                unsigned &Line, unsigned &Column) const {    SourceManager &SourceMgr = Context->getSourceManager();    FileManager &FileMgr = SourceMgr.getFileManager(); -  StringRef Filename; -  unsigned Line, Column;    SourceLocation DILoc;    if (D.isLocationAvailable()) { @@ -455,6 +441,7 @@ void BackendConsumer::EmitOptimizationMessage(        // source manager, so pass 1 if Column is not set.        DILoc = SourceMgr.translateFileLineCol(FE, Line, Column ? Column : 1);      } +    BadDebugInfo = DILoc.isInvalid();    }    // If a location isn't available, try to approximate it using the associated @@ -463,18 +450,63 @@ void BackendConsumer::EmitOptimizationMessage(    FullSourceLoc Loc(DILoc, SourceMgr);    if (Loc.isInvalid())      if (const Decl *FD = Gen->GetDeclForMangledName(D.getFunction().getName())) -      Loc = FD->getASTContext().getFullLoc(FD->getBodyRBrace()); +      Loc = FD->getASTContext().getFullLoc(FD->getLocation()); + +  if (DILoc.isInvalid() && D.isLocationAvailable()) +    // If we were not able to translate the file:line:col information +    // back to a SourceLocation, at least emit a note stating that +    // we could not translate this location. This can happen in the +    // case of #line directives. +    Diags.Report(Loc, diag::note_fe_backend_invalid_loc) +        << Filename << Line << Column; + +  return Loc; +} + +void BackendConsumer::UnsupportedDiagHandler( +    const llvm::DiagnosticInfoUnsupported &D) { +  // We only support errors. +  assert(D.getSeverity() == llvm::DS_Error); + +  StringRef Filename; +  unsigned Line, Column; +  bool BadDebugInfo; +  FullSourceLoc Loc = getBestLocationFromDebugLoc(D, BadDebugInfo, Filename, +      Line, Column); + +  Diags.Report(Loc, diag::err_fe_backend_unsupported) << D.getMessage().str(); + +  if (BadDebugInfo) +    // If we were not able to translate the file:line:col information +    // back to a SourceLocation, at least emit a note stating that +    // we could not translate this location. This can happen in the +    // case of #line directives. +    Diags.Report(Loc, diag::note_fe_backend_invalid_loc) +        << Filename << Line << Column; +} + +void BackendConsumer::EmitOptimizationMessage( +    const llvm::DiagnosticInfoOptimizationBase &D, unsigned DiagID) { +  // We only support warnings and remarks. +  assert(D.getSeverity() == llvm::DS_Remark || +         D.getSeverity() == llvm::DS_Warning); + +  StringRef Filename; +  unsigned Line, Column; +  bool BadDebugInfo = false; +  FullSourceLoc Loc = getBestLocationFromDebugLoc(D, BadDebugInfo, Filename, +      Line, Column);    Diags.Report(Loc, DiagID)        << AddFlagValue(D.getPassName() ? D.getPassName() : "")        << D.getMsg().str(); -  if (DILoc.isInvalid() && D.isLocationAvailable()) +  if (BadDebugInfo)      // If we were not able to translate the file:line:col information      // back to a SourceLocation, at least emit a note stating that      // we could not translate this location. This can happen in the      // case of #line directives. -    Diags.Report(Loc, diag::note_fe_backend_optimization_remark_invalid_loc) +    Diags.Report(Loc, diag::note_fe_backend_invalid_loc)          << Filename << Line << Column;  } @@ -504,7 +536,7 @@ void BackendConsumer::OptimizationRemarkHandler(    // llvm::DiagnosticInfo::AlwasyPrint or if the -Rpass-analysis flag has a    // regular expression that matches the name of the pass name in \p D. -  if (D.getPassName() == llvm::DiagnosticInfo::AlwaysPrint || +  if (D.shouldAlwaysPrint() ||        (CodeGenOpts.OptimizationRemarkAnalysisPattern &&         CodeGenOpts.OptimizationRemarkAnalysisPattern->match(D.getPassName())))      EmitOptimizationMessage( @@ -517,7 +549,7 @@ void BackendConsumer::OptimizationRemarkHandler(    // llvm::DiagnosticInfo::AlwasyPrint or if the -Rpass-analysis flag has a    // regular expression that matches the name of the pass name in \p D. -  if (D.getPassName() == llvm::DiagnosticInfo::AlwaysPrint || +  if (D.shouldAlwaysPrint() ||        (CodeGenOpts.OptimizationRemarkAnalysisPattern &&         CodeGenOpts.OptimizationRemarkAnalysisPattern->match(D.getPassName())))      EmitOptimizationMessage( @@ -530,7 +562,7 @@ void BackendConsumer::OptimizationRemarkHandler(    // llvm::DiagnosticInfo::AlwasyPrint or if the -Rpass-analysis flag has a    // regular expression that matches the name of the pass name in \p D. -  if (D.getPassName() == llvm::DiagnosticInfo::AlwaysPrint || +  if (D.shouldAlwaysPrint() ||        (CodeGenOpts.OptimizationRemarkAnalysisPattern &&         CodeGenOpts.OptimizationRemarkAnalysisPattern->match(D.getPassName())))      EmitOptimizationMessage( @@ -599,6 +631,9 @@ void BackendConsumer::DiagnosticHandlerImpl(const DiagnosticInfo &DI) {      // handler.      OptimizationFailureHandler(cast<DiagnosticInfoOptimizationFailure>(DI));      return; +  case llvm::DK_Unsupported: +    UnsupportedDiagHandler(cast<DiagnosticInfoUnsupported>(DI)); +    return;    default:      // Plugin IDs are not bound to any value as they are set dynamically.      ComputeDiagRemarkID(Severity, backend_plugin, DiagID); @@ -657,7 +692,7 @@ llvm::LLVMContext *CodeGenAction::takeLLVMContext() {    return VMContext;  } -static raw_pwrite_stream * +static std::unique_ptr<raw_pwrite_stream>  GetOutputStream(CompilerInstance &CI, StringRef InFile, BackendAction Action) {    switch (Action) {    case Backend_EmitAssembly: @@ -680,7 +715,7 @@ GetOutputStream(CompilerInstance &CI, StringRef InFile, BackendAction Action) {  std::unique_ptr<ASTConsumer>  CodeGenAction::CreateASTConsumer(CompilerInstance &CI, StringRef InFile) {    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)      return nullptr; @@ -720,7 +755,7 @@ CodeGenAction::CreateASTConsumer(CompilerInstance &CI, StringRef InFile) {        BA, CI.getDiagnostics(), CI.getHeaderSearchOpts(),        CI.getPreprocessorOpts(), CI.getCodeGenOpts(), CI.getTargetOpts(),        CI.getLangOpts(), CI.getFrontendOpts().ShowTimers, InFile, LinkModules, -      OS, *VMContext, CoverageInfo)); +      std::move(OS), *VMContext, CoverageInfo));    BEConsumer = Result.get();    return std::move(Result);  } @@ -729,6 +764,22 @@ static void BitcodeInlineAsmDiagHandler(const llvm::SMDiagnostic &SM,                                           void *Context,                                           unsigned LocCookie) {    SM.print(nullptr, llvm::errs()); + +  auto Diags = static_cast<DiagnosticsEngine *>(Context); +  unsigned DiagID; +  switch (SM.getKind()) { +  case llvm::SourceMgr::DK_Error: +    DiagID = diag::err_fe_inline_asm; +    break; +  case llvm::SourceMgr::DK_Warning: +    DiagID = diag::warn_fe_inline_asm; +    break; +  case llvm::SourceMgr::DK_Note: +    DiagID = diag::note_fe_inline_asm; +    break; +  } + +  Diags->Report(DiagID).AddString("cannot compile inline asm");  }  void CodeGenAction::ExecuteAction() { @@ -736,7 +787,8 @@ void CodeGenAction::ExecuteAction() {    if (getCurrentFileKind() == IK_LLVM_IR) {      BackendAction BA = static_cast<BackendAction>(Act);      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)        return; @@ -747,6 +799,11 @@ void CodeGenAction::ExecuteAction() {      if (Invalid)        return; +    // For ThinLTO backend invocations, ensure that the context +    // merges types based on ODR identifiers. +    if (!CI.getCodeGenOpts().ThinLTOIndexFile.empty()) +      VMContext->enableDebugTypeODRUniquing(); +      llvm::SMDiagnostic Err;      TheModule = parseIR(MainFile->getMemBufferRef(), Err, *VMContext);      if (!TheModule) { @@ -779,11 +836,16 @@ void CodeGenAction::ExecuteAction() {        TheModule->setTargetTriple(TargetOpts.Triple);      } +    EmbedBitcode(TheModule.get(), CI.getCodeGenOpts(), +                 MainFile->getMemBufferRef()); +      LLVMContext &Ctx = TheModule->getContext(); -    Ctx.setInlineAsmDiagnosticHandler(BitcodeInlineAsmDiagHandler); +    Ctx.setInlineAsmDiagnosticHandler(BitcodeInlineAsmDiagHandler, +                                      &CI.getDiagnostics()); +      EmitBackendOutput(CI.getDiagnostics(), CI.getCodeGenOpts(), TargetOpts, -                      CI.getLangOpts(), CI.getTarget().getDataLayoutString(), -                      TheModule.get(), BA, OS); +                      CI.getLangOpts(), CI.getTarget().getDataLayout(), +                      TheModule.get(), BA, std::move(OS));      return;    }  | 
