diff options
author | dim <dim@FreeBSD.org> | 2014-11-24 18:11:16 +0000 |
---|---|---|
committer | dim <dim@FreeBSD.org> | 2014-11-24 18:11:16 +0000 |
commit | 6148c19c738a92f344008aa3f88f4e008bada0ee (patch) | |
tree | d4426858455f04d0d8c25a2f9eb9ea5582ffe1b6 /contrib/llvm/tools/clang/lib/CodeGen/CodeGenAction.cpp | |
parent | 2c8643c6396b0a3db33430cf9380e70bbb9efce0 (diff) | |
parent | 173a4f43a911175643bda81ee675e8d9269056ea (diff) | |
download | FreeBSD-src-6148c19c738a92f344008aa3f88f4e008bada0ee.zip FreeBSD-src-6148c19c738a92f344008aa3f88f4e008bada0ee.tar.gz |
Merge clang 3.5.0 release from ^/vendor/clang/dist, resolve conflicts,
and preserve our customizations, where necessary.
Diffstat (limited to 'contrib/llvm/tools/clang/lib/CodeGen/CodeGenAction.cpp')
-rw-r--r-- | contrib/llvm/tools/clang/lib/CodeGen/CodeGenAction.cpp | 447 |
1 files changed, 355 insertions, 92 deletions
diff --git a/contrib/llvm/tools/clang/lib/CodeGen/CodeGenAction.cpp b/contrib/llvm/tools/clang/lib/CodeGen/CodeGenAction.cpp index 3072204..04d2cd9 100644 --- a/contrib/llvm/tools/clang/lib/CodeGen/CodeGenAction.cpp +++ b/contrib/llvm/tools/clang/lib/CodeGen/CodeGenAction.cpp @@ -11,6 +11,7 @@ #include "clang/AST/ASTConsumer.h" #include "clang/AST/ASTContext.h" #include "clang/AST/DeclGroup.h" +#include "clang/AST/DeclCXX.h" #include "clang/Basic/FileManager.h" #include "clang/Basic/SourceManager.h" #include "clang/Basic/TargetInfo.h" @@ -18,17 +19,20 @@ #include "clang/CodeGen/ModuleBuilder.h" #include "clang/Frontend/CompilerInstance.h" #include "clang/Frontend/FrontendDiagnostic.h" -#include "llvm/ADT/OwningPtr.h" #include "llvm/ADT/SmallString.h" #include "llvm/Bitcode/ReaderWriter.h" +#include "llvm/IR/DebugInfo.h" +#include "llvm/IR/DiagnosticInfo.h" +#include "llvm/IR/DiagnosticPrinter.h" #include "llvm/IR/LLVMContext.h" #include "llvm/IR/Module.h" #include "llvm/IRReader/IRReader.h" -#include "llvm/Linker.h" +#include "llvm/Linker/Linker.h" #include "llvm/Pass.h" #include "llvm/Support/MemoryBuffer.h" #include "llvm/Support/SourceMgr.h" #include "llvm/Support/Timer.h" +#include <memory> using namespace clang; using namespace llvm; @@ -45,42 +49,33 @@ namespace clang { Timer LLVMIRGeneration; - OwningPtr<CodeGenerator> Gen; + std::unique_ptr<CodeGenerator> Gen; - OwningPtr<llvm::Module> TheModule, LinkModule; + std::unique_ptr<llvm::Module> TheModule, LinkModule; public: BackendConsumer(BackendAction action, DiagnosticsEngine &_Diags, const CodeGenOptions &compopts, const TargetOptions &targetopts, - const LangOptions &langopts, - bool TimePasses, - const std::string &infile, - llvm::Module *LinkModule, - raw_ostream *OS, - LLVMContext &C) : - 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)), - LinkModule(LinkModule) - { + const LangOptions &langopts, bool TimePasses, + const std::string &infile, llvm::Module *LinkModule, + raw_ostream *OS, LLVMContext &C) + : 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)), + LinkModule(LinkModule) { llvm::TimePassesIsEnabled = TimePasses; } - llvm::Module *takeModule() { return TheModule.take(); } - llvm::Module *takeLinkModule() { return LinkModule.take(); } + llvm::Module *takeModule() { return TheModule.release(); } + llvm::Module *takeLinkModule() { return LinkModule.release(); } - virtual void HandleCXXStaticMemberVarInstantiation(VarDecl *VD) { + void HandleCXXStaticMemberVarInstantiation(VarDecl *VD) override { Gen->HandleCXXStaticMemberVarInstantiation(VD); } - virtual void Initialize(ASTContext &Ctx) { + void Initialize(ASTContext &Ctx) override { Context = &Ctx; if (llvm::TimePassesIsEnabled) @@ -94,7 +89,7 @@ namespace clang { LLVMIRGeneration.stopTimer(); } - virtual bool HandleTopLevelDecl(DeclGroupRef D) { + bool HandleTopLevelDecl(DeclGroupRef D) override { PrettyStackTraceDecl CrashInfo(*D.begin(), SourceLocation(), Context->getSourceManager(), "LLVM IR generation of declaration"); @@ -110,7 +105,20 @@ namespace clang { return true; } - virtual void HandleTranslationUnit(ASTContext &C) { + void HandleInlineMethodDefinition(CXXMethodDecl *D) override { + PrettyStackTraceDecl CrashInfo(D, SourceLocation(), + Context->getSourceManager(), + "LLVM IR generation of inline method"); + if (llvm::TimePassesIsEnabled) + LLVMIRGeneration.startTimer(); + + Gen->HandleInlineMethodDefinition(D); + + if (llvm::TimePassesIsEnabled) + LLVMIRGeneration.stopTimer(); + } + + void HandleTranslationUnit(ASTContext &C) override { { PrettyStackTraceString CrashInfo("Per-file LLVM IR generation"); if (llvm::TimePassesIsEnabled) @@ -132,7 +140,7 @@ namespace clang { if (!M) { // The module has been released by IR gen on failures, do not double // free. - TheModule.take(); + TheModule.release(); return; } @@ -158,41 +166,49 @@ namespace clang { void *OldContext = Ctx.getInlineAsmDiagnosticContext(); Ctx.setInlineAsmDiagnosticHandler(InlineAsmDiagHandler, this); + LLVMContext::DiagnosticHandlerTy OldDiagnosticHandler = + Ctx.getDiagnosticHandler(); + void *OldDiagnosticContext = Ctx.getDiagnosticContext(); + Ctx.setDiagnosticHandler(DiagnosticHandler, this); + EmitBackendOutput(Diags, CodeGenOpts, TargetOpts, LangOpts, + C.getTargetInfo().getTargetDescription(), TheModule.get(), Action, AsmOutStream); - + Ctx.setInlineAsmDiagnosticHandler(OldHandler, OldContext); + + Ctx.setDiagnosticHandler(OldDiagnosticHandler, OldDiagnosticContext); } - virtual void HandleTagDeclDefinition(TagDecl *D) { + void HandleTagDeclDefinition(TagDecl *D) override { PrettyStackTraceDecl CrashInfo(D, SourceLocation(), Context->getSourceManager(), "LLVM IR generation of declaration"); Gen->HandleTagDeclDefinition(D); } - virtual void HandleTagDeclRequiredDefinition(const TagDecl *D) { + void HandleTagDeclRequiredDefinition(const TagDecl *D) override { Gen->HandleTagDeclRequiredDefinition(D); } - virtual void CompleteTentativeDefinition(VarDecl *D) { + void CompleteTentativeDefinition(VarDecl *D) override { Gen->CompleteTentativeDefinition(D); } - virtual void HandleVTable(CXXRecordDecl *RD, bool DefinitionRequired) { + void HandleVTable(CXXRecordDecl *RD, bool DefinitionRequired) override { Gen->HandleVTable(RD, DefinitionRequired); } - virtual void HandleLinkerOptionPragma(llvm::StringRef Opts) { + void HandleLinkerOptionPragma(llvm::StringRef Opts) override { Gen->HandleLinkerOptionPragma(Opts); } - virtual void HandleDetectMismatch(llvm::StringRef Name, - llvm::StringRef Value) { + void HandleDetectMismatch(llvm::StringRef Name, + llvm::StringRef Value) override { Gen->HandleDetectMismatch(Name, Value); } - virtual void HandleDependentLibrary(llvm::StringRef Opts) { + void HandleDependentLibrary(llvm::StringRef Opts) override { Gen->HandleDependentLibrary(Opts); } @@ -202,8 +218,36 @@ namespace clang { ((BackendConsumer*)Context)->InlineAsmDiagHandler2(SM, Loc); } + static void DiagnosticHandler(const llvm::DiagnosticInfo &DI, + void *Context) { + ((BackendConsumer *)Context)->DiagnosticHandlerImpl(DI); + } + void InlineAsmDiagHandler2(const llvm::SMDiagnostic &, SourceLocation LocCookie); + + void DiagnosticHandlerImpl(const llvm::DiagnosticInfo &DI); + /// \brief Specialized handler for InlineAsm diagnostic. + /// \return True if the diagnostic has been successfully reported, false + /// otherwise. + bool InlineAsmDiagHandler(const llvm::DiagnosticInfoInlineAsm &D); + /// \brief Specialized handler for StackSize diagnostic. + /// \return True if the diagnostic has been successfully reported, false + /// otherwise. + bool StackSizeDiagHandler(const llvm::DiagnosticInfoStackSize &D); + /// \brief Specialized handlers for optimization remarks. + /// Note that these handlers only accept remarks and they always handle + /// them. + void EmitOptimizationMessage(const llvm::DiagnosticInfoOptimizationBase &D, + unsigned DiagID); + void + OptimizationRemarkHandler(const llvm::DiagnosticInfoOptimizationRemark &D); + void OptimizationRemarkHandler( + const llvm::DiagnosticInfoOptimizationRemarkMissed &D); + void OptimizationRemarkHandler( + const llvm::DiagnosticInfoOptimizationRemarkAnalysis &D); + void OptimizationFailureHandler( + const llvm::DiagnosticInfoOptimizationFailure &D); }; void BackendConsumer::anchor() {} @@ -224,13 +268,15 @@ static FullSourceLoc ConvertBackendLocation(const llvm::SMDiagnostic &D, LSM.getMemoryBuffer(LSM.FindBufferContainingLoc(D.getLoc())); // 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()); - FileID FID = CSM.createFileIDForMemBuffer(CBuf); + // FIXME: Keep a file ID map instead of creating new IDs for each location. + FileID FID = CSM.createFileID(CBuf); // Translate the offset into the file. - unsigned Offset = D.getLoc().getPointer() - LBuf->getBufferStart(); + unsigned Offset = D.getLoc().getPointer() - LBuf->getBufferStart(); SourceLocation NewLoc = CSM.getLocForStartOfFile(FID).getLocWithOffset(Offset); return FullSourceLoc(NewLoc, CSM); @@ -254,13 +300,24 @@ void BackendConsumer::InlineAsmDiagHandler2(const llvm::SMDiagnostic &D, FullSourceLoc Loc; if (D.getLoc() != SMLoc()) Loc = ConvertBackendLocation(D, Context->getSourceManager()); - + unsigned DiagID; + switch (D.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; + } // If this problem has clang-level source location information, report the - // issue as being an error in the source with a note showing the instantiated + // issue in the source with a note showing the instantiated // code. if (LocCookie.isValid()) { - Diags.Report(LocCookie, diag::err_fe_inline_asm).AddString(Message); + Diags.Report(LocCookie, DiagID).AddString(Message); if (D.getLoc().isValid()) { DiagnosticBuilder B = Diags.Report(Loc, diag::note_fe_inline_asm_here); @@ -276,16 +333,224 @@ void BackendConsumer::InlineAsmDiagHandler2(const llvm::SMDiagnostic &D, return; } - // Otherwise, report the backend error as occurring in the generated .s file. - // If Loc is invalid, we still need to report the error, it just gets no + // Otherwise, report the backend issue as occurring in the generated .s file. + // If Loc is invalid, we still need to report the issue, it just gets no // location info. - Diags.Report(Loc, diag::err_fe_inline_asm).AddString(Message); + Diags.Report(Loc, DiagID).AddString(Message); } -// +#define ComputeDiagID(Severity, GroupName, DiagID) \ + do { \ + switch (Severity) { \ + case llvm::DS_Error: \ + DiagID = diag::err_fe_##GroupName; \ + break; \ + case llvm::DS_Warning: \ + DiagID = diag::warn_fe_##GroupName; \ + break; \ + case llvm::DS_Remark: \ + llvm_unreachable("'remark' severity not expected"); \ + break; \ + case llvm::DS_Note: \ + DiagID = diag::note_fe_##GroupName; \ + break; \ + } \ + } while (false) + +#define ComputeDiagRemarkID(Severity, GroupName, DiagID) \ + do { \ + switch (Severity) { \ + case llvm::DS_Error: \ + DiagID = diag::err_fe_##GroupName; \ + break; \ + case llvm::DS_Warning: \ + DiagID = diag::warn_fe_##GroupName; \ + break; \ + case llvm::DS_Remark: \ + DiagID = diag::remark_fe_##GroupName; \ + break; \ + case llvm::DS_Note: \ + DiagID = diag::note_fe_##GroupName; \ + break; \ + } \ + } while (false) + +bool +BackendConsumer::InlineAsmDiagHandler(const llvm::DiagnosticInfoInlineAsm &D) { + unsigned DiagID; + ComputeDiagID(D.getSeverity(), inline_asm, DiagID); + std::string Message = D.getMsgStr().str(); + + // If this problem has clang-level source location information, report the + // issue as being a problem in the source with a note showing the instantiated + // code. + SourceLocation LocCookie = + SourceLocation::getFromRawEncoding(D.getLocCookie()); + if (LocCookie.isValid()) + Diags.Report(LocCookie, DiagID).AddString(Message); + else { + // Otherwise, report the backend diagnostic as occurring in the generated + // .s file. + // If Loc is invalid, we still need to report the diagnostic, it just gets + // no location info. + FullSourceLoc Loc; + Diags.Report(Loc, DiagID).AddString(Message); + } + // We handled all the possible severities. + return true; +} + +bool +BackendConsumer::StackSizeDiagHandler(const llvm::DiagnosticInfoStackSize &D) { + if (D.getSeverity() != llvm::DS_Warning) + // For now, the only support we have for StackSize diagnostic is warning. + // We do not know how to format other severities. + return false; + + if (const Decl *ND = Gen->GetDeclForMangledName(D.getFunction().getName())) { + Diags.Report(ND->getASTContext().getFullLoc(ND->getLocation()), + diag::warn_fe_frame_larger_than) + << 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); + + SourceManager &SourceMgr = Context->getSourceManager(); + FileManager &FileMgr = SourceMgr.getFileManager(); + StringRef Filename; + unsigned Line, Column; + D.getLocation(&Filename, &Line, &Column); + SourceLocation DILoc; + const FileEntry *FE = FileMgr.getFile(Filename); + if (FE && Line > 0) { + // If -gcolumn-info was not used, Column will be 0. This upsets the + // source manager, so pass 1 if Column is not set. + DILoc = SourceMgr.translateFileLineCol(FE, Line, Column ? Column : 1); + } + + // If a location isn't available, try to approximate it using the associated + // function definition. We use the definition's right brace to differentiate + // from diagnostics that genuinely relate to the function itself. + FullSourceLoc Loc(DILoc, SourceMgr); + if (Loc.isInvalid()) + if (const Decl *FD = Gen->GetDeclForMangledName(D.getFunction().getName())) + Loc = FD->getASTContext().getFullLoc(FD->getBodyRBrace()); + + Diags.Report(Loc, DiagID) + << AddFlagValue(D.getPassName() ? D.getPassName() : "") + << D.getMsg().str(); + + if (DILoc.isInvalid()) + // 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) + << Filename << Line << Column; +} + +void BackendConsumer::OptimizationRemarkHandler( + const llvm::DiagnosticInfoOptimizationRemark &D) { + // Optimization remarks are active only if the -Rpass flag has a regular + // expression that matches the name of the pass name in \p D. + if (CodeGenOpts.OptimizationRemarkPattern && + CodeGenOpts.OptimizationRemarkPattern->match(D.getPassName())) + EmitOptimizationMessage(D, diag::remark_fe_backend_optimization_remark); +} + +void BackendConsumer::OptimizationRemarkHandler( + const llvm::DiagnosticInfoOptimizationRemarkMissed &D) { + // Missed optimization remarks are active only if the -Rpass-missed + // flag has a regular expression that matches the name of the pass + // name in \p D. + if (CodeGenOpts.OptimizationRemarkMissedPattern && + CodeGenOpts.OptimizationRemarkMissedPattern->match(D.getPassName())) + EmitOptimizationMessage(D, + diag::remark_fe_backend_optimization_remark_missed); +} + +void BackendConsumer::OptimizationRemarkHandler( + const llvm::DiagnosticInfoOptimizationRemarkAnalysis &D) { + // Optimization analysis remarks are active only if the -Rpass-analysis + // flag has a regular expression that matches the name of the pass + // name in \p D. + if (CodeGenOpts.OptimizationRemarkAnalysisPattern && + CodeGenOpts.OptimizationRemarkAnalysisPattern->match(D.getPassName())) + EmitOptimizationMessage( + D, diag::remark_fe_backend_optimization_remark_analysis); +} + +void BackendConsumer::OptimizationFailureHandler( + const llvm::DiagnosticInfoOptimizationFailure &D) { + EmitOptimizationMessage(D, diag::warn_fe_backend_optimization_failure); +} + +/// \brief This function is invoked when the backend needs +/// to report something to the user. +void BackendConsumer::DiagnosticHandlerImpl(const DiagnosticInfo &DI) { + unsigned DiagID = diag::err_fe_inline_asm; + llvm::DiagnosticSeverity Severity = DI.getSeverity(); + // Get the diagnostic ID based. + switch (DI.getKind()) { + case llvm::DK_InlineAsm: + if (InlineAsmDiagHandler(cast<DiagnosticInfoInlineAsm>(DI))) + return; + ComputeDiagID(Severity, inline_asm, DiagID); + break; + case llvm::DK_StackSize: + if (StackSizeDiagHandler(cast<DiagnosticInfoStackSize>(DI))) + return; + ComputeDiagID(Severity, backend_frame_larger_than, DiagID); + break; + case llvm::DK_OptimizationRemark: + // Optimization remarks are always handled completely by this + // handler. There is no generic way of emitting them. + OptimizationRemarkHandler(cast<DiagnosticInfoOptimizationRemark>(DI)); + return; + case llvm::DK_OptimizationRemarkMissed: + // Optimization remarks are always handled completely by this + // handler. There is no generic way of emitting them. + OptimizationRemarkHandler(cast<DiagnosticInfoOptimizationRemarkMissed>(DI)); + return; + case llvm::DK_OptimizationRemarkAnalysis: + // Optimization remarks are always handled completely by this + // handler. There is no generic way of emitting them. + OptimizationRemarkHandler( + cast<DiagnosticInfoOptimizationRemarkAnalysis>(DI)); + return; + case llvm::DK_OptimizationFailure: + // Optimization failures are always handled completely by this + // handler. + OptimizationFailureHandler(cast<DiagnosticInfoOptimizationFailure>(DI)); + return; + default: + // Plugin IDs are not bound to any value as they are set dynamically. + ComputeDiagRemarkID(Severity, backend_plugin, DiagID); + break; + } + std::string MsgStorage; + { + raw_string_ostream Stream(MsgStorage); + DiagnosticPrinterRawOStream DP(Stream); + DI.print(DP); + } + + // Report the backend message using the usual diagnostic mechanism. + FullSourceLoc Loc; + Diags.Report(Loc, DiagID).AddString(MsgStorage); +} +#undef ComputeDiagID CodeGenAction::CodeGenAction(unsigned _Act, LLVMContext *_VMContext) - : Act(_Act), LinkModule(0), + : Act(_Act), LinkModule(nullptr), VMContext(_VMContext ? _VMContext : new LLVMContext), OwnsVMContext(!_VMContext) {} @@ -310,9 +575,7 @@ void CodeGenAction::EndSourceFileAction() { TheModule.reset(BEConsumer->takeModule()); } -llvm::Module *CodeGenAction::takeModule() { - return TheModule.take(); -} +llvm::Module *CodeGenAction::takeModule() { return TheModule.release(); } llvm::LLVMContext *CodeGenAction::takeLLVMContext() { OwnsVMContext = false; @@ -330,8 +593,9 @@ static raw_ostream *GetOutputStream(CompilerInstance &CI, case Backend_EmitBC: return CI.createDefaultOutputFile(true, InFile, "bc"); case Backend_EmitNothing: - return 0; + return nullptr; case Backend_EmitMCNull: + return CI.createNullOutputFile(); case Backend_EmitObj: return CI.createDefaultOutputFile(true, InFile, "o"); } @@ -342,9 +606,9 @@ static raw_ostream *GetOutputStream(CompilerInstance &CI, ASTConsumer *CodeGenAction::CreateASTConsumer(CompilerInstance &CI, StringRef InFile) { BackendAction BA = static_cast<BackendAction>(Act); - OwningPtr<raw_ostream> OS(GetOutputStream(CI, InFile, BA)); + std::unique_ptr<raw_ostream> OS(GetOutputStream(CI, InFile, BA)); if (BA != Backend_EmitNothing && !OS) - return 0; + return nullptr; llvm::Module *LinkModuleToUse = LinkModule; @@ -359,23 +623,23 @@ ASTConsumer *CodeGenAction::CreateASTConsumer(CompilerInstance &CI, if (!BCBuf) { CI.getDiagnostics().Report(diag::err_cannot_open_file) << LinkBCFile << ErrorStr; - return 0; + return nullptr; } - LinkModuleToUse = getLazyBitcodeModule(BCBuf, *VMContext, &ErrorStr); - if (!LinkModuleToUse) { + ErrorOr<llvm::Module *> ModuleOrErr = + getLazyBitcodeModule(BCBuf, *VMContext); + if (std::error_code EC = ModuleOrErr.getError()) { CI.getDiagnostics().Report(diag::err_cannot_open_file) - << LinkBCFile << ErrorStr; - return 0; + << LinkBCFile << EC.message(); + return nullptr; } + LinkModuleToUse = ModuleOrErr.get(); } - BEConsumer = - new BackendConsumer(BA, CI.getDiagnostics(), - CI.getCodeGenOpts(), CI.getTargetOpts(), - CI.getLangOpts(), - CI.getFrontendOpts().ShowTimers, InFile, - LinkModuleToUse, OS.take(), *VMContext); + BEConsumer = new BackendConsumer(BA, CI.getDiagnostics(), CI.getCodeGenOpts(), + CI.getTargetOpts(), CI.getLangOpts(), + CI.getFrontendOpts().ShowTimers, InFile, + LinkModuleToUse, OS.release(), *VMContext); return BEConsumer; } @@ -390,49 +654,48 @@ void CodeGenAction::ExecuteAction() { bool Invalid; SourceManager &SM = CI.getSourceManager(); - const llvm::MemoryBuffer *MainFile = SM.getBuffer(SM.getMainFileID(), - &Invalid); + FileID FID = SM.getMainFileID(); + llvm::MemoryBuffer *MainFile = SM.getBuffer(FID, &Invalid); if (Invalid) return; - // FIXME: This is stupid, IRReader shouldn't take ownership. - llvm::MemoryBuffer *MainFileCopy = - llvm::MemoryBuffer::getMemBufferCopy(MainFile->getBuffer(), - getCurrentFile()); - llvm::SMDiagnostic Err; - TheModule.reset(ParseIR(MainFileCopy, Err, *VMContext)); + TheModule.reset(ParseIR(MainFile, Err, *VMContext)); if (!TheModule) { - // Translate from the diagnostic info to the SourceManager location. - SourceLocation Loc = SM.translateFileLineCol( - SM.getFileEntryForID(SM.getMainFileID()), Err.getLineNo(), - Err.getColumnNo() + 1); + // Translate from the diagnostic info to the SourceManager location if + // available. + // TODO: Unify this with ConvertBackendLocation() + SourceLocation Loc; + if (Err.getLineNo() > 0) { + assert(Err.getColumnNo() >= 0); + Loc = SM.translateFileLineCol(SM.getFileEntryForID(FID), + Err.getLineNo(), Err.getColumnNo() + 1); + } - // Get a custom diagnostic for the error. We strip off a leading - // diagnostic code if there is one. + // Strip off a leading diagnostic code if there is one. StringRef Msg = Err.getMessage(); if (Msg.startswith("error: ")) Msg = Msg.substr(7); - // Escape '%', which is interpreted as a format character. - SmallString<128> EscapedMessage; - for (unsigned i = 0, e = Msg.size(); i != e; ++i) { - if (Msg[i] == '%') - EscapedMessage += '%'; - EscapedMessage += Msg[i]; - } + unsigned DiagID = + CI.getDiagnostics().getCustomDiagID(DiagnosticsEngine::Error, "%0"); + CI.getDiagnostics().Report(Loc, DiagID) << Msg; + return; + } + const TargetOptions &TargetOpts = CI.getTargetOpts(); + if (TheModule->getTargetTriple() != TargetOpts.Triple) { unsigned DiagID = CI.getDiagnostics().getCustomDiagID( - DiagnosticsEngine::Error, EscapedMessage); + DiagnosticsEngine::Warning, + "overriding the module target triple with %0"); - CI.getDiagnostics().Report(Loc, DiagID); - return; + CI.getDiagnostics().Report(SourceLocation(), DiagID) << TargetOpts.Triple; + TheModule->setTargetTriple(TargetOpts.Triple); } - EmitBackendOutput(CI.getDiagnostics(), CI.getCodeGenOpts(), - CI.getTargetOpts(), CI.getLangOpts(), - TheModule.get(), - BA, OS); + EmitBackendOutput(CI.getDiagnostics(), CI.getCodeGenOpts(), TargetOpts, + CI.getLangOpts(), CI.getTarget().getTargetDescription(), + TheModule.get(), BA, OS); return; } |