From owner-svn-src-all@freebsd.org Wed Apr 26 19:33:58 2017 Return-Path: Delivered-To: svn-src-all@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 1F528D511B3; Wed, 26 Apr 2017 19:33:58 +0000 (UTC) (envelope-from dim@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id ECF831AD0; Wed, 26 Apr 2017 19:33:57 +0000 (UTC) (envelope-from dim@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id v3QJXunb035217; Wed, 26 Apr 2017 19:33:56 GMT (envelope-from dim@FreeBSD.org) Received: (from dim@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id v3QJXuVx035211; Wed, 26 Apr 2017 19:33:56 GMT (envelope-from dim@FreeBSD.org) Message-Id: <201704261933.v3QJXuVx035211@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: dim set sender to dim@FreeBSD.org using -f From: Dimitry Andric Date: Wed, 26 Apr 2017 19:33:56 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r317458 - in head/contrib/llvm: include/llvm/CodeGen include/llvm/MC include/llvm/MC/MCParser lib/CodeGen/AsmPrinter lib/MC lib/MC/MCParser X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 26 Apr 2017 19:33:58 -0000 Author: dim Date: Wed Apr 26 19:33:56 2017 New Revision: 317458 URL: https://svnweb.freebsd.org/changeset/base/317458 Log: Pull in r294458 from upstream llvm trunk (by Sanne Wouda): [Assembler] Enable nicer diagnostics for inline assembly. Fixed test. Summary: Enables source location in diagnostic messages from the backend. This is after parsing, during finalization. This requires the SourceMgr, the inline assembly string buffer, and DiagInfo to still be alive after EmitInlineAsm returns. This patch creates a single SourceMgr for inline assembly inside the AsmPrinter. MCContext gets a pointer to this SourceMgr. Using one SourceMgr per call to EmitInlineAsm would make it difficult for MCContext to figure out in which SourceMgr the SMLoc is located, while a single SourceMgr can figure it out if it has multiple buffers. The Str argument to EmitInlineAsm is copied into a buffer and owned by the inline asm SourceMgr. This ensures that DiagHandlers won't print garbage. (Clang emits a "note: instantiated into assembly here", which refers to this string.) The AsmParser gets destroyed before finalization, which means that the DiagHandlers the AsmParser installs into the SourceMgr will be stale. Restore the saved DiagHandlers. Since now we're using just one SourceMgr for multiple inline asm strings, we need to tell the AsmParser which buffer it needs to parse currently. Hand a buffer id -- returned from SourceMgr:: AddNewSourceBuffer -- to the AsmParser. Reviewers: rnk, grosbach, compnerd, rengolin, rovka, anemet Reviewed By: rnk Subscribers: llvm-commits Differential Revision: https://reviews.llvm.org/D29441 This improves error reporting for some inline assembly constructs that clang does not approve of: instead of crashing with a "fatal backend error", it will now show a normal error message, and point out the location of the problematic assembly. Reported by: mmel MFC after: 1 week Modified: head/contrib/llvm/include/llvm/CodeGen/AsmPrinter.h head/contrib/llvm/include/llvm/MC/MCContext.h head/contrib/llvm/include/llvm/MC/MCParser/MCAsmParser.h head/contrib/llvm/lib/CodeGen/AsmPrinter/AsmPrinterInlineAsm.cpp head/contrib/llvm/lib/MC/MCContext.cpp head/contrib/llvm/lib/MC/MCParser/AsmParser.cpp Modified: head/contrib/llvm/include/llvm/CodeGen/AsmPrinter.h ============================================================================== --- head/contrib/llvm/include/llvm/CodeGen/AsmPrinter.h Wed Apr 26 19:26:40 2017 (r317457) +++ head/contrib/llvm/include/llvm/CodeGen/AsmPrinter.h Wed Apr 26 19:33:56 2017 (r317458) @@ -23,6 +23,7 @@ #include "llvm/IR/InlineAsm.h" #include "llvm/Support/DataTypes.h" #include "llvm/Support/ErrorHandling.h" +#include "llvm/Support/SourceMgr.h" namespace llvm { class AsmPrinterHandler; @@ -137,6 +138,19 @@ private: /// maintains ownership of the emitters. SmallVector Handlers; +public: + struct SrcMgrDiagInfo { + SourceMgr SrcMgr; + const MDNode *LocInfo; + LLVMContext::InlineAsmDiagHandlerTy DiagHandler; + void *DiagContext; + }; + +private: + /// Structure for generating diagnostics for inline assembly. Only initialised + /// when necessary. + mutable std::unique_ptr DiagInfo; + /// If the target supports dwarf debug info, this pointer is non-null. DwarfDebug *DD; Modified: head/contrib/llvm/include/llvm/MC/MCContext.h ============================================================================== --- head/contrib/llvm/include/llvm/MC/MCContext.h Wed Apr 26 19:26:40 2017 (r317457) +++ head/contrib/llvm/include/llvm/MC/MCContext.h Wed Apr 26 19:33:56 2017 (r317458) @@ -59,6 +59,9 @@ namespace llvm { /// The SourceMgr for this object, if any. const SourceMgr *SrcMgr; + /// The SourceMgr for inline assembly, if any. + SourceMgr *InlineSrcMgr; + /// The MCAsmInfo for this target. const MCAsmInfo *MAI; @@ -240,6 +243,8 @@ namespace llvm { const SourceMgr *getSourceManager() const { return SrcMgr; } + void setInlineSourceManager(SourceMgr *SM) { InlineSrcMgr = SM; } + const MCAsmInfo *getAsmInfo() const { return MAI; } const MCRegisterInfo *getRegisterInfo() const { return MRI; } Modified: head/contrib/llvm/include/llvm/MC/MCParser/MCAsmParser.h ============================================================================== --- head/contrib/llvm/include/llvm/MC/MCParser/MCAsmParser.h Wed Apr 26 19:26:40 2017 (r317457) +++ head/contrib/llvm/include/llvm/MC/MCParser/MCAsmParser.h Wed Apr 26 19:33:56 2017 (r317458) @@ -258,7 +258,7 @@ public: /// \brief Create an MCAsmParser instance. MCAsmParser *createMCAsmParser(SourceMgr &, MCContext &, MCStreamer &, - const MCAsmInfo &); + const MCAsmInfo &, unsigned CB = 0); } // End llvm namespace Modified: head/contrib/llvm/lib/CodeGen/AsmPrinter/AsmPrinterInlineAsm.cpp ============================================================================== --- head/contrib/llvm/lib/CodeGen/AsmPrinter/AsmPrinterInlineAsm.cpp Wed Apr 26 19:26:40 2017 (r317457) +++ head/contrib/llvm/lib/CodeGen/AsmPrinter/AsmPrinterInlineAsm.cpp Wed Apr 26 19:33:56 2017 (r317458) @@ -40,19 +40,12 @@ using namespace llvm; #define DEBUG_TYPE "asm-printer" -namespace { - struct SrcMgrDiagInfo { - const MDNode *LocInfo; - LLVMContext::InlineAsmDiagHandlerTy DiagHandler; - void *DiagContext; - }; -} - /// srcMgrDiagHandler - This callback is invoked when the SourceMgr for an /// inline asm has an error in it. diagInfo is a pointer to the SrcMgrDiagInfo /// struct above. static void srcMgrDiagHandler(const SMDiagnostic &Diag, void *diagInfo) { - SrcMgrDiagInfo *DiagInfo = static_cast(diagInfo); + AsmPrinter::SrcMgrDiagInfo *DiagInfo = + static_cast(diagInfo); assert(DiagInfo && "Diagnostic context not passed down?"); // If the inline asm had metadata associated with it, pull out a location @@ -99,35 +92,34 @@ void AsmPrinter::EmitInlineAsm(StringRef return; } - SourceMgr SrcMgr; - SrcMgr.setIncludeDirs(MCOptions.IASSearchPaths); + if (!DiagInfo) { + DiagInfo = make_unique(); - SrcMgrDiagInfo DiagInfo; + MCContext &Context = MMI->getContext(); + Context.setInlineSourceManager(&DiagInfo->SrcMgr); - // If the current LLVMContext has an inline asm handler, set it in SourceMgr. - LLVMContext &LLVMCtx = MMI->getModule()->getContext(); - bool HasDiagHandler = false; - if (LLVMCtx.getInlineAsmDiagnosticHandler() != nullptr) { - // If the source manager has an issue, we arrange for srcMgrDiagHandler - // to be invoked, getting DiagInfo passed into it. - DiagInfo.LocInfo = LocMDNode; - DiagInfo.DiagHandler = LLVMCtx.getInlineAsmDiagnosticHandler(); - DiagInfo.DiagContext = LLVMCtx.getInlineAsmDiagnosticContext(); - SrcMgr.setDiagHandler(srcMgrDiagHandler, &DiagInfo); - HasDiagHandler = true; + LLVMContext &LLVMCtx = MMI->getModule()->getContext(); + if (LLVMCtx.getInlineAsmDiagnosticHandler()) { + DiagInfo->DiagHandler = LLVMCtx.getInlineAsmDiagnosticHandler(); + DiagInfo->DiagContext = LLVMCtx.getInlineAsmDiagnosticContext(); + DiagInfo->SrcMgr.setDiagHandler(srcMgrDiagHandler, DiagInfo.get()); + } } + SourceMgr &SrcMgr = DiagInfo->SrcMgr; + SrcMgr.setIncludeDirs(MCOptions.IASSearchPaths); + DiagInfo->LocInfo = LocMDNode; + std::unique_ptr Buffer; - if (isNullTerminated) - Buffer = MemoryBuffer::getMemBuffer(Str, ""); - else - Buffer = MemoryBuffer::getMemBufferCopy(Str, ""); + // The inline asm source manager will outlive Str, so make a copy of the + // string for SourceMgr to own. + Buffer = MemoryBuffer::getMemBufferCopy(Str, ""); // Tell SrcMgr about this buffer, it takes ownership of the buffer. - SrcMgr.AddNewSourceBuffer(std::move(Buffer), SMLoc()); + unsigned BufNum = SrcMgr.AddNewSourceBuffer(std::move(Buffer), SMLoc()); std::unique_ptr Parser( - createMCAsmParser(SrcMgr, OutContext, *OutStreamer, *MAI)); + createMCAsmParser(SrcMgr, OutContext, *OutStreamer, *MAI, BufNum)); // We create a new MCInstrInfo here since we might be at the module level // and not have a MachineFunction to initialize the TargetInstrInfo from and @@ -151,7 +143,13 @@ void AsmPrinter::EmitInlineAsm(StringRef int Res = Parser->Run(/*NoInitialTextSection*/ true, /*NoFinalize*/ true); emitInlineAsmEnd(STI, &TAP->getSTI()); - if (Res && !HasDiagHandler) + + // LocInfo cannot be used for error generation from the backend. + // FIXME: associate LocInfo with the SourceBuffer to improve backend + // messages. + DiagInfo->LocInfo = nullptr; + + if (Res && !DiagInfo->DiagHandler) report_fatal_error("Error parsing inline asm\n"); } Modified: head/contrib/llvm/lib/MC/MCContext.cpp ============================================================================== --- head/contrib/llvm/lib/MC/MCContext.cpp Wed Apr 26 19:26:40 2017 (r317457) +++ head/contrib/llvm/lib/MC/MCContext.cpp Wed Apr 26 19:33:56 2017 (r317458) @@ -510,13 +510,15 @@ CodeViewContext &MCContext::getCVContext void MCContext::reportError(SMLoc Loc, const Twine &Msg) { HadError = true; - // If we have a source manager use it. Otherwise just use the generic - // report_fatal_error(). - if (!SrcMgr) + // If we have a source manager use it. Otherwise, try using the inline source + // manager. + // If that fails, use the generic report_fatal_error(). + if (SrcMgr) + SrcMgr->PrintMessage(Loc, SourceMgr::DK_Error, Msg); + else if (InlineSrcMgr) + InlineSrcMgr->PrintMessage(Loc, SourceMgr::DK_Error, Msg); + else report_fatal_error(Msg, false); - - // Use the source manager to print the message. - SrcMgr->PrintMessage(Loc, SourceMgr::DK_Error, Msg); } void MCContext::reportFatalError(SMLoc Loc, const Twine &Msg) { Modified: head/contrib/llvm/lib/MC/MCParser/AsmParser.cpp ============================================================================== --- head/contrib/llvm/lib/MC/MCParser/AsmParser.cpp Wed Apr 26 19:26:40 2017 (r317457) +++ head/contrib/llvm/lib/MC/MCParser/AsmParser.cpp Wed Apr 26 19:33:56 2017 (r317458) @@ -209,7 +209,7 @@ private: public: AsmParser(SourceMgr &SM, MCContext &Ctx, MCStreamer &Out, - const MCAsmInfo &MAI); + const MCAsmInfo &MAI, unsigned CB); ~AsmParser() override; bool Run(bool NoInitialTextSection, bool NoFinalize = false) override; @@ -572,9 +572,9 @@ extern MCAsmParserExtension *createCOFFA enum { DEFAULT_ADDRSPACE = 0 }; AsmParser::AsmParser(SourceMgr &SM, MCContext &Ctx, MCStreamer &Out, - const MCAsmInfo &MAI) + const MCAsmInfo &MAI, unsigned CB = 0) : Lexer(MAI), Ctx(Ctx), Out(Out), MAI(MAI), SrcMgr(SM), - PlatformParser(nullptr), CurBuffer(SM.getMainFileID()), + PlatformParser(nullptr), CurBuffer(CB ? CB : SM.getMainFileID()), MacrosEnabledFlag(true), CppHashInfo(), AssemblerDialect(~0U), IsDarwin(false), ParsingInlineAsm(false) { HadError = false; @@ -608,6 +608,10 @@ AsmParser::AsmParser(SourceMgr &SM, MCCo AsmParser::~AsmParser() { assert((HadError || ActiveMacros.empty()) && "Unexpected active macro instantiation!"); + + // Restore the saved diagnostics handler and context for use during + // finalization. + SrcMgr.setDiagHandler(SavedDiagHandler, SavedDiagContext); } void AsmParser::printMacroInstantiations() { @@ -5518,6 +5522,7 @@ bool parseAssignmentExpression(StringRef /// \brief Create an MCAsmParser instance. MCAsmParser *llvm::createMCAsmParser(SourceMgr &SM, MCContext &C, - MCStreamer &Out, const MCAsmInfo &MAI) { - return new AsmParser(SM, C, Out, MAI); + MCStreamer &Out, const MCAsmInfo &MAI, + unsigned CB) { + return new AsmParser(SM, C, Out, MAI, CB); }