Index: include/clang/Basic/Diagnostic.h =================================================================== --- include/clang/Basic/Diagnostic.h +++ include/clang/Basic/Diagnostic.h @@ -22,9 +22,10 @@ #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/IntrusiveRefCntPtr.h" -#include "llvm/ADT/iterator_range.h" #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/StringRef.h" +#include "llvm/ADT/iterator_range.h" +#include "llvm/Support/SMLoc.h" #include #include #include @@ -36,6 +37,11 @@ #include #include +namespace llvm { + +class SourceMgr; +} + namespace clang { class DeclContext; @@ -733,6 +739,8 @@ /// which can be an invalid location if no position information is available. inline DiagnosticBuilder Report(SourceLocation Loc, unsigned DiagID); inline DiagnosticBuilder Report(unsigned DiagID); + inline DiagnosticBuilder Report(const llvm::SourceMgr *SM, llvm::SMLoc Loc, + unsigned DiagID); void Report(const StoredDiagnostic &storedDiag); @@ -786,7 +794,7 @@ friend class DiagnosticErrorTrap; /// \brief The location of the current diagnostic that is in flight. - SourceLocation CurDiagLoc; + UnifiedSourceLoc CurDiagLoc; /// \brief The ID of the current diagnostic that is in flight. /// @@ -1180,7 +1188,12 @@ inline DiagnosticBuilder DiagnosticsEngine::Report(SourceLocation Loc, unsigned DiagID) { assert(CurDiagID == ~0U && "Multiple diagnostics in flight at once!"); - CurDiagLoc = Loc; + + if (!Loc.isValid() || !hasSourceManager()) + CurDiagLoc = UnifiedSourceLoc(); + else + CurDiagLoc = UnifiedSourceLoc(Loc, getSourceManager()); + CurDiagID = DiagID; FlagValue.clear(); return DiagnosticBuilder(this); @@ -1190,6 +1203,19 @@ return Report(SourceLocation(), DiagID); } +inline DiagnosticBuilder DiagnosticsEngine::Report(const llvm::SourceMgr *SM, + llvm::SMLoc Loc, + unsigned DiagID) { + auto DB = Report(DiagID); + + if (!Loc.isValid() || !SM) + CurDiagLoc = UnifiedSourceLoc(); + else + CurDiagLoc = UnifiedSourceLoc(Loc, *SM); + + return DB; +} + //===----------------------------------------------------------------------===// // Diagnostic //===----------------------------------------------------------------------===// @@ -1208,7 +1234,7 @@ const DiagnosticsEngine *getDiags() const { return DiagObj; } unsigned getID() const { return DiagObj->CurDiagID; } - const SourceLocation &getLocation() const { return DiagObj->CurDiagLoc; } + const UnifiedSourceLoc &getLocation() const { return DiagObj->CurDiagLoc; } bool hasSourceManager() const { return DiagObj->hasSourceManager(); } SourceManager &getSourceManager() const { return DiagObj->getSourceManager();} Index: include/clang/Basic/SourceLocation.h =================================================================== --- include/clang/Basic/SourceLocation.h +++ include/clang/Basic/SourceLocation.h @@ -18,6 +18,7 @@ #include "clang/Basic/LLVM.h" #include "llvm/Support/Compiler.h" #include "llvm/Support/PointerLikeTypeTraits.h" +#include "llvm/Support/SMLoc.h" #include #include #include @@ -25,6 +26,7 @@ namespace llvm { class MemoryBuffer; + class SourceMgr; template struct DenseMapInfo; template struct isPodLike; } @@ -418,7 +420,59 @@ }; +class UnifiedPLoc : public PresumedLoc { + const llvm::SourceMgr *SrcMgr = nullptr; + llvm::SMLoc Loc = llvm::SMLoc(); +public: + UnifiedPLoc() : PresumedLoc() {} + UnifiedPLoc(PresumedLoc Loc) : PresumedLoc(Loc) {} + explicit UnifiedPLoc(llvm::SMLoc Loc, const llvm::SourceMgr &SM) + : PresumedLoc(), SrcMgr(&SM), Loc(Loc) {} + + bool isValid() const; + bool isInvalid() const; + unsigned getLine() const; + unsigned getColumn() const; + StringRef getFilename() const; + + SourceLocation getIncludeLoc() const; +}; + +class UnifiedSourceLoc : public FullSourceLoc { + const llvm::SourceMgr *SrcMgr = nullptr; + llvm::SMLoc Loc = llvm::SMLoc(); + +public: + UnifiedSourceLoc() : FullSourceLoc() {} + UnifiedSourceLoc(FullSourceLoc Loc) : FullSourceLoc(Loc) {} + UnifiedSourceLoc(SourceLocation Loc, const SourceManager &SM) + : FullSourceLoc(Loc, SM) {} + explicit UnifiedSourceLoc(llvm::SMLoc Loc, const llvm::SourceMgr &SM) + : FullSourceLoc(), SrcMgr(&SM), Loc(Loc) {} + + bool isValid() const; + UnifiedSourceLoc getFileLoc() const; + UnifiedPLoc getPresumedLoc(bool UseLineDirectives = true) const; + bool isLLVMLocation() const; + std::pair getDecomposedLoc() const; + StringRef getBufferData(bool *Invalid = nullptr) const; + unsigned getLineNumber() const; + unsigned getColumnNumber() const; + + friend inline bool operator==(const UnifiedSourceLoc &LHS, + const UnifiedSourceLoc &RHS) { + if (!LHS.SrcMgr && !RHS.SrcMgr) + return static_cast(LHS) == static_cast(RHS); + + return LHS.Loc == RHS.Loc && LHS.SrcMgr == RHS.SrcMgr; + } + + friend inline bool operator!=(const UnifiedSourceLoc &LHS, + const UnifiedSourceLoc &RHS) { + return !(LHS == RHS); + } +}; } // end namespace clang Index: include/clang/Driver/Options.h =================================================================== --- include/clang/Driver/Options.h +++ include/clang/Driver/Options.h @@ -15,10 +15,13 @@ namespace llvm { namespace opt { class OptTable; +class ArgList; } } namespace clang { +class DiagnosticOptions; +class DiagnosticsEngine; namespace driver { namespace options { Index: include/clang/Driver/Options.td =================================================================== --- include/clang/Driver/Options.td +++ include/clang/Driver/Options.td @@ -433,7 +433,7 @@ MetaVarName<"">, Group; def Wwrite_strings : Flag<["-"], "Wwrite-strings">, Group, Flags<[CC1Option, HelpHidden]>; def Wno_write_strings : Flag<["-"], "Wno-write-strings">, Group, Flags<[CC1Option, HelpHidden]>; -def W_Joined : Joined<["-"], "W">, Group, Flags<[CC1Option, CoreOption]>, +def W_Joined : Joined<["-"], "W">, Group, Flags<[CC1Option, CC1AsOption, CoreOption]>, MetaVarName<"">, HelpText<"Enable the specified warning">; def Xanalyzer : Separate<["-"], "Xanalyzer">, HelpText<"Pass to the static analyzer">, MetaVarName<"">, @@ -685,7 +685,7 @@ def fcaret_diagnostics : Flag<["-"], "fcaret-diagnostics">, Group; def fclasspath_EQ : Joined<["-"], "fclasspath=">, Group; def fcolor_diagnostics : Flag<["-"], "fcolor-diagnostics">, Group, - Flags<[CoreOption, CC1Option]>, HelpText<"Use colors in diagnostics">; + Flags<[CoreOption, CC1Option, CC1AsOption]>, HelpText<"Use colors in diagnostics">; def fdiagnostics_color : Flag<["-"], "fdiagnostics-color">, Group, Flags<[CoreOption, DriverOption]>; def fdiagnostics_color_EQ : Joined<["-"], "fdiagnostics-color=">, Group; @@ -2208,7 +2208,7 @@ def weak__reference__mismatches : Separate<["-"], "weak_reference_mismatches">; def whatsloaded : Flag<["-"], "whatsloaded">; def whyload : Flag<["-"], "whyload">; -def w : Flag<["-"], "w">, HelpText<"Suppress all warnings">, Flags<[CC1Option]>; +def w : Flag<["-"], "w">, HelpText<"Suppress all warnings">, Flags<[CC1Option,CC1AsOption]>; def x : JoinedOrSeparate<["-"], "x">, Flags<[DriverOption,CC1Option]>, HelpText<"Treat subsequent input files as having type ">, MetaVarName<"">; Index: include/clang/Frontend/DiagnosticRenderer.h =================================================================== --- include/clang/Frontend/DiagnosticRenderer.h +++ include/clang/Frontend/DiagnosticRenderer.h @@ -52,8 +52,8 @@ /// This will be invalid in cases where there is no (known) previous /// diagnostic location, or that location itself is invalid or comes from /// a different source manager than SM. - SourceLocation LastLoc; - + UnifiedSourceLoc LastLoc; + /// \brief The location of the last include whose stack was printed if known. /// /// Same restriction as LastLoc essentially, but tracking include stack @@ -71,25 +71,26 @@ virtual ~DiagnosticRenderer(); - virtual void emitDiagnosticMessage(FullSourceLoc Loc, PresumedLoc PLoc, + virtual void emitDiagnosticMessage(UnifiedSourceLoc Loc, UnifiedPLoc PLoc, DiagnosticsEngine::Level Level, StringRef Message, ArrayRef Ranges, DiagOrStoredDiag Info) = 0; - virtual void emitDiagnosticLoc(FullSourceLoc Loc, PresumedLoc PLoc, + virtual void emitDiagnosticLoc(UnifiedSourceLoc Loc, UnifiedPLoc PLoc, DiagnosticsEngine::Level Level, ArrayRef Ranges) = 0; - virtual void emitCodeContext(FullSourceLoc Loc, + virtual void emitCodeContext(UnifiedSourceLoc Loc, DiagnosticsEngine::Level Level, SmallVectorImpl &Ranges, ArrayRef Hints) = 0; - virtual void emitIncludeLocation(FullSourceLoc Loc, PresumedLoc PLoc) = 0; - virtual void emitImportLocation(FullSourceLoc Loc, PresumedLoc PLoc, + virtual void emitIncludeLocation(UnifiedSourceLoc Loc, UnifiedPLoc PLoc) = 0; + virtual void emitImportLocation(UnifiedSourceLoc Loc, UnifiedPLoc PLoc, StringRef ModuleName) = 0; - virtual void emitBuildingModuleLocation(FullSourceLoc Loc, PresumedLoc PLoc, + virtual void emitBuildingModuleLocation(UnifiedSourceLoc Loc, + UnifiedPLoc PLoc, StringRef ModuleName) = 0; virtual void beginDiagnostic(DiagOrStoredDiag D, @@ -100,18 +101,18 @@ private: void emitBasicNote(StringRef Message); - void emitIncludeStack(FullSourceLoc Loc, PresumedLoc PLoc, + void emitIncludeStack(UnifiedSourceLoc Loc, UnifiedPLoc PLoc, DiagnosticsEngine::Level Level); - void emitIncludeStackRecursively(FullSourceLoc Loc); - void emitImportStack(FullSourceLoc Loc); - void emitImportStackRecursively(FullSourceLoc Loc, StringRef ModuleName); + void emitIncludeStackRecursively(UnifiedSourceLoc Loc); + void emitImportStack(UnifiedSourceLoc Loc); + void emitImportStackRecursively(UnifiedSourceLoc Loc, StringRef ModuleName); void emitModuleBuildStack(const SourceManager &SM); - void emitCaret(FullSourceLoc Loc, DiagnosticsEngine::Level Level, + void emitCaret(UnifiedSourceLoc Loc, DiagnosticsEngine::Level Level, ArrayRef Ranges, ArrayRef Hints); - void emitSingleMacroExpansion(FullSourceLoc Loc, + void emitSingleMacroExpansion(UnifiedSourceLoc Loc, DiagnosticsEngine::Level Level, ArrayRef Ranges); - void emitMacroExpansions(FullSourceLoc Loc, DiagnosticsEngine::Level Level, + void emitMacroExpansions(UnifiedSourceLoc Loc, DiagnosticsEngine::Level Level, ArrayRef Ranges, ArrayRef Hints); @@ -130,7 +131,7 @@ /// \param FixItHints The FixIt hints active for this diagnostic. /// \param SM The SourceManager; will be null if the diagnostic came from the /// frontend, thus \p Loc will be invalid. - void emitDiagnostic(FullSourceLoc Loc, DiagnosticsEngine::Level Level, + void emitDiagnostic(UnifiedSourceLoc Loc, DiagnosticsEngine::Level Level, StringRef Message, ArrayRef Ranges, ArrayRef FixItHints, DiagOrStoredDiag D = (Diagnostic *)nullptr); @@ -148,15 +149,15 @@ ~DiagnosticNoteRenderer() override; - void emitIncludeLocation(FullSourceLoc Loc, PresumedLoc PLoc) override; + void emitIncludeLocation(UnifiedSourceLoc Loc, UnifiedPLoc PLoc) override; - void emitImportLocation(FullSourceLoc Loc, PresumedLoc PLoc, + void emitImportLocation(UnifiedSourceLoc Loc, UnifiedPLoc PLoc, StringRef ModuleName) override; - void emitBuildingModuleLocation(FullSourceLoc Loc, PresumedLoc PLoc, + void emitBuildingModuleLocation(UnifiedSourceLoc Loc, UnifiedPLoc PLoc, StringRef ModuleName) override; - virtual void emitNote(FullSourceLoc Loc, StringRef Message) = 0; + virtual void emitNote(UnifiedSourceLoc Loc, StringRef Message) = 0; }; } // end clang namespace #endif Index: include/clang/Frontend/TextDiagnostic.h =================================================================== --- include/clang/Frontend/TextDiagnostic.h +++ include/clang/Frontend/TextDiagnostic.h @@ -75,33 +75,33 @@ unsigned Columns, bool ShowColors); protected: - void emitDiagnosticMessage(FullSourceLoc Loc, PresumedLoc PLoc, + void emitDiagnosticMessage(UnifiedSourceLoc Loc, UnifiedPLoc PLoc, DiagnosticsEngine::Level Level, StringRef Message, ArrayRef Ranges, DiagOrStoredDiag D) override; - void emitDiagnosticLoc(FullSourceLoc Loc, PresumedLoc PLoc, + void emitDiagnosticLoc(UnifiedSourceLoc Loc, UnifiedPLoc PLoc, DiagnosticsEngine::Level Level, ArrayRef Ranges) override; - void emitCodeContext(FullSourceLoc Loc, DiagnosticsEngine::Level Level, + void emitCodeContext(UnifiedSourceLoc Loc, DiagnosticsEngine::Level Level, SmallVectorImpl &Ranges, ArrayRef Hints) override { emitSnippetAndCaret(Loc, Level, Ranges, Hints); } - void emitIncludeLocation(FullSourceLoc Loc, PresumedLoc PLoc) override; + void emitIncludeLocation(UnifiedSourceLoc Loc, UnifiedPLoc PLoc) override; - void emitImportLocation(FullSourceLoc Loc, PresumedLoc PLoc, + void emitImportLocation(UnifiedSourceLoc Loc, UnifiedPLoc PLoc, StringRef ModuleName) override; - void emitBuildingModuleLocation(FullSourceLoc Loc, PresumedLoc PLoc, + void emitBuildingModuleLocation(UnifiedSourceLoc Loc, UnifiedPLoc PLoc, StringRef ModuleName) override; private: - void emitFilename(StringRef Filename, const SourceManager &SM); + void emitFilename(StringRef Filename, const SourceManager *SM); - void emitSnippetAndCaret(FullSourceLoc Loc, DiagnosticsEngine::Level Level, + void emitSnippetAndCaret(UnifiedSourceLoc Loc, DiagnosticsEngine::Level Level, SmallVectorImpl &Ranges, ArrayRef Hints); Index: lib/Basic/SourceLocation.cpp =================================================================== --- lib/Basic/SourceLocation.cpp +++ lib/Basic/SourceLocation.cpp @@ -101,8 +101,7 @@ std::pair FullSourceLoc::getImmediateExpansionRange() const { assert(isValid()); - std::pair Range = - SrcMgr->getImmediateExpansionRange(*this); + auto Range = SrcMgr->getImmediateExpansionRange(*this); return std::make_pair(FullSourceLoc(Range.first, *SrcMgr), FullSourceLoc(Range.second, *SrcMgr)); } @@ -128,8 +127,7 @@ if (!isValid()) return std::make_pair(FullSourceLoc(), StringRef()); - std::pair ImportLoc = - SrcMgr->getModuleImportLoc(*this); + auto ImportLoc = SrcMgr->getModuleImportLoc(*this); return std::make_pair(FullSourceLoc(ImportLoc.first, *SrcMgr), ImportLoc.second); } @@ -152,8 +150,7 @@ std::pair FullSourceLoc::getExpansionRange() const { assert(isValid()); - std::pair Range = - SrcMgr->getExpansionRange(*this); + auto Range = SrcMgr->getExpansionRange(*this); return std::make_pair(FullSourceLoc(Range.first, *SrcMgr), FullSourceLoc(Range.second, *SrcMgr)); } @@ -211,4 +208,100 @@ return SrcMgr->getDecomposedLoc(*this); } +bool UnifiedSourceLoc::isValid() const { + if (!SrcMgr) + return FullSourceLoc::isValid(); + + return Loc.isValid(); +} + +UnifiedSourceLoc UnifiedSourceLoc::getFileLoc() const { + if (!SrcMgr) + return FullSourceLoc::getFileLoc(); + + // Just return the current location. + return *this; +} + +UnifiedPLoc UnifiedSourceLoc::getPresumedLoc(bool UseLineDirectives) const { + if (!SrcMgr) + return FullSourceLoc::getPresumedLoc(UseLineDirectives); + + // Return the current location as a PresumedLoc. + return UnifiedPLoc(Loc, *SrcMgr); +} + +bool UnifiedSourceLoc::isLLVMLocation() const { return !!SrcMgr; } + +std::pair UnifiedSourceLoc::getDecomposedLoc() const { + if (!SrcMgr) + return FullSourceLoc::getDecomposedLoc(); + + unsigned Offset = Loc.getPointer() - getBufferData().data(); + return std::make_pair(FileID(), Offset); +} + +StringRef UnifiedSourceLoc::getBufferData(bool *Invalid) const { + if (!SrcMgr) + return FullSourceLoc::getBufferData(Invalid); + + unsigned BufID = SrcMgr->FindBufferContainingLoc(Loc); + return SrcMgr->getMemoryBuffer(BufID)->getBuffer(); +} + +unsigned UnifiedSourceLoc::getLineNumber() const { + if (!SrcMgr) + return FullSourceLoc::getLineNumber(); + + return SrcMgr->getLineAndColumn(Loc).first; +} + +unsigned UnifiedSourceLoc::getColumnNumber() const { + if (!SrcMgr) + return FullSourceLoc::getColumnNumber(); + + return SrcMgr->getLineAndColumn(Loc).second; +} + +bool UnifiedPLoc::isValid() const { + if (!SrcMgr) + return PresumedLoc::isValid(); + + return Loc.isValid(); +} + +bool UnifiedPLoc::isInvalid() const { return !isValid(); } + +unsigned UnifiedPLoc::getLine() const { + if (!SrcMgr) + return PresumedLoc::getLine(); + + return SrcMgr->getLineAndColumn(Loc).first; +} + +unsigned UnifiedPLoc::getColumn() const { + if (!SrcMgr) + return PresumedLoc::getColumn(); + + return SrcMgr->getLineAndColumn(Loc).second; +} + +StringRef UnifiedPLoc::getFilename() const { + if (!SrcMgr) + return PresumedLoc::getFilename(); + + unsigned CurBuf = SrcMgr->FindBufferContainingLoc(Loc); + assert(CurBuf && "Invalid or unspecified location!"); + + const llvm::MemoryBuffer *CurMB = SrcMgr->getMemoryBuffer(CurBuf); + return CurMB->getBufferIdentifier(); +} + +SourceLocation UnifiedPLoc::getIncludeLoc() const { + if (!SrcMgr) + return PresumedLoc::getIncludeLoc(); + + return SourceLocation(); +} + } // end namespace clang Index: lib/Driver/DriverOptions.cpp =================================================================== --- lib/Driver/DriverOptions.cpp +++ lib/Driver/DriverOptions.cpp @@ -7,10 +7,17 @@ // //===----------------------------------------------------------------------===// +#include "clang/Basic/Diagnostic.h" +#include "clang/Basic/DiagnosticOptions.h" +#include "clang/Driver/DriverDiagnostic.h" #include "clang/Driver/Options.h" +#include "clang/Frontend/Utils.h" #include "llvm/ADT/STLExtras.h" +#include "llvm/ADT/StringRef.h" +#include "llvm/Option/ArgList.h" #include "llvm/Option/OptTable.h" #include "llvm/Option/Option.h" +#include "llvm/Support/Process.h" using namespace clang::driver; using namespace clang::driver::options; Index: lib/Driver/ToolChains/Clang.cpp =================================================================== --- lib/Driver/ToolChains/Clang.cpp +++ lib/Driver/ToolChains/Clang.cpp @@ -28,6 +28,7 @@ #include "clang/Driver/Options.h" #include "clang/Driver/SanitizerArgs.h" #include "clang/Driver/XRayArgs.h" +#include "clang/Frontend/TextDiagnosticPrinter.h" #include "llvm/ADT/StringExtras.h" #include "llvm/Option/ArgList.h" #include "llvm/Support/CodeGen.h" @@ -1684,6 +1685,33 @@ CDB << ", \"" << escape(Buf) << "\"]},\n"; } +static void CollectArgsForColorDiagnostics(const ArgList &Args, + ArgStringList &CmdArgs, + const Driver &D) { + // Color diagnostics are parsed by the driver directly from argv + // and later re-parsed to construct this job; claim any possible + // color diagnostic here to avoid warn_drv_unused_argument and + // diagnose bad OPT_fdiagnostics_color_EQ values. + for (Arg *A : Args) { + const Option &O = A->getOption(); + if (!O.matches(options::OPT_fcolor_diagnostics) && + !O.matches(options::OPT_fdiagnostics_color) && + !O.matches(options::OPT_fno_color_diagnostics) && + !O.matches(options::OPT_fno_diagnostics_color) && + !O.matches(options::OPT_fdiagnostics_color_EQ)) + continue; + if (O.matches(options::OPT_fdiagnostics_color_EQ)) { + StringRef Value(A->getValue()); + if (Value != "always" && Value != "never" && Value != "auto") + D.Diag(diag::err_drv_clang_unsupported) + << ("-fdiagnostics-color=" + Value).str(); + } + A->claim(); + } + if (D.getDiags().getDiagnosticOptions().ShowColors) + CmdArgs.push_back("-fcolor-diagnostics"); +} + static void CollectArgsForIntegratedAssembler(Compilation &C, const ArgList &Args, ArgStringList &CmdArgs, @@ -4005,28 +4033,7 @@ CmdArgs.push_back("-fno-diagnostics-show-note-include-stack"); } - // Color diagnostics are parsed by the driver directly from argv - // and later re-parsed to construct this job; claim any possible - // color diagnostic here to avoid warn_drv_unused_argument and - // diagnose bad OPT_fdiagnostics_color_EQ values. - for (Arg *A : Args) { - const Option &O = A->getOption(); - if (!O.matches(options::OPT_fcolor_diagnostics) && - !O.matches(options::OPT_fdiagnostics_color) && - !O.matches(options::OPT_fno_color_diagnostics) && - !O.matches(options::OPT_fno_diagnostics_color) && - !O.matches(options::OPT_fdiagnostics_color_EQ)) - continue; - if (O.matches(options::OPT_fdiagnostics_color_EQ)) { - StringRef Value(A->getValue()); - if (Value != "always" && Value != "never" && Value != "auto") - getToolChain().getDriver().Diag(diag::err_drv_clang_unsupported) - << ("-fdiagnostics-color=" + Value).str(); - } - A->claim(); - } - if (D.getDiags().getDiagnosticOptions().ShowColors) - CmdArgs.push_back("-fcolor-diagnostics"); + CollectArgsForColorDiagnostics(Args, CmdArgs, getToolChain().getDriver()); if (Args.hasArg(options::OPT_fansi_escape_codes)) CmdArgs.push_back("-fansi-escape-codes"); @@ -4857,9 +4864,7 @@ const llvm::Triple &Triple = getToolChain().getEffectiveTriple(); const std::string &TripleStr = Triple.getTriple(); - // Don't warn about "clang -w -c foo.s" - Args.ClaimAllArgs(options::OPT_w); - // and "clang -emit-llvm -c foo.s" + // Don't warn about "clang -emit-llvm -c foo.s" Args.ClaimAllArgs(options::OPT_emit_llvm); claimNoWarnArgs(Args); @@ -4998,12 +5003,11 @@ break; } - // Consume all the warning flags. Usually this would be handled more - // gracefully by -cc1 (warning about unknown warning flags, etc) but -cc1as - // doesn't handle that so rather than warning about unused flags that are - // actually used, we'll lie by omission instead. - // FIXME: Stop lying and consume only the appropriate driver flags - Args.ClaimAllArgs(options::OPT_W_Group); + // Pass all warning flags to -cc1as. + Args.AddAllArgs(CmdArgs, options::OPT_W_Group); + Args.AddLastArg(CmdArgs, options::OPT_w); + + CollectArgsForColorDiagnostics(Args, CmdArgs, getToolChain().getDriver()); CollectArgsForIntegratedAssembler(C, Args, CmdArgs, getToolChain().getDriver()); Index: lib/Frontend/DiagnosticRenderer.cpp =================================================================== --- lib/Frontend/DiagnosticRenderer.cpp +++ lib/Frontend/DiagnosticRenderer.cpp @@ -76,19 +76,17 @@ } } -void DiagnosticRenderer::emitDiagnostic(FullSourceLoc Loc, +void DiagnosticRenderer::emitDiagnostic(UnifiedSourceLoc Loc, DiagnosticsEngine::Level Level, StringRef Message, ArrayRef Ranges, ArrayRef FixItHints, DiagOrStoredDiag D) { - assert(Loc.hasManager() || Loc.isInvalid()); - beginDiagnostic(D, Level); if (!Loc.isValid()) // If we have no source location, just emit the diagnostic message. - emitDiagnosticMessage(Loc, PresumedLoc(), Level, Message, Ranges, D); + emitDiagnosticMessage(Loc, UnifiedPLoc(), Level, Message, Ranges, D); else { // Get the ranges into a local array we can hack on. SmallVector MutableRanges(Ranges.begin(), @@ -106,16 +104,17 @@ if (I->RemoveRange.isValid()) MutableRanges.push_back(I->RemoveRange); - FullSourceLoc UnexpandedLoc = Loc; + UnifiedSourceLoc UnexpandedLoc = Loc; // Find the ultimate expansion location for the diagnostic. Loc = Loc.getFileLoc(); - PresumedLoc PLoc = Loc.getPresumedLoc(DiagOpts->ShowPresumedLoc); + UnifiedPLoc PLoc = Loc.getPresumedLoc(DiagOpts->ShowPresumedLoc); // First, if this diagnostic is not in the main file, print out the // "included from" lines. - emitIncludeStack(Loc, PLoc, Level); + if (!Loc.isLLVMLocation()) + emitIncludeStack(Loc, PLoc, Level); // Next, emit the actual diagnostic message and caret. emitDiagnosticMessage(Loc, PLoc, Level, Message, Ranges, D); @@ -145,8 +144,9 @@ } void DiagnosticRenderer::emitBasicNote(StringRef Message) { - emitDiagnosticMessage(FullSourceLoc(), PresumedLoc(), DiagnosticsEngine::Note, - Message, None, DiagOrStoredDiag()); + emitDiagnosticMessage(UnifiedSourceLoc(), UnifiedPLoc(), + DiagnosticsEngine::Note, Message, None, + DiagOrStoredDiag()); } /// \brief Prints an include stack when appropriate for a particular @@ -160,11 +160,13 @@ /// \param Loc The diagnostic location. /// \param PLoc The presumed location of the diagnostic location. /// \param Level The diagnostic level of the message this stack pertains to. -void DiagnosticRenderer::emitIncludeStack(FullSourceLoc Loc, PresumedLoc PLoc, +void DiagnosticRenderer::emitIncludeStack(UnifiedSourceLoc Loc, + UnifiedPLoc PLoc, DiagnosticsEngine::Level Level) { - FullSourceLoc IncludeLoc = - PLoc.isInvalid() ? FullSourceLoc() - : FullSourceLoc(PLoc.getIncludeLoc(), Loc.getManager()); + UnifiedSourceLoc IncludeLoc = + PLoc.isInvalid() + ? UnifiedSourceLoc() + : UnifiedSourceLoc(PLoc.getIncludeLoc(), Loc.getManager()); // Skip redundant include stacks altogether. if (LastIncludeLoc == IncludeLoc) @@ -185,20 +187,20 @@ /// \brief Helper to recursivly walk up the include stack and print each layer /// on the way back down. -void DiagnosticRenderer::emitIncludeStackRecursively(FullSourceLoc Loc) { +void DiagnosticRenderer::emitIncludeStackRecursively(UnifiedSourceLoc Loc) { if (Loc.isInvalid()) { emitModuleBuildStack(Loc.getManager()); return; } - PresumedLoc PLoc = Loc.getPresumedLoc(DiagOpts->ShowPresumedLoc); + UnifiedPLoc PLoc = Loc.getPresumedLoc(DiagOpts->ShowPresumedLoc); if (PLoc.isInvalid()) return; // If this source location was imported from a module, print the module // import stack rather than the // FIXME: We want submodule granularity here. - std::pair Imported = Loc.getModuleImportLoc(); + std::pair Imported = Loc.getModuleImportLoc(); if (!Imported.second.empty()) { // This location was imported by a module. Emit the module import stack. emitImportStackRecursively(Imported.first, Imported.second); @@ -207,35 +209,37 @@ // Emit the other include frames first. emitIncludeStackRecursively( - FullSourceLoc(PLoc.getIncludeLoc(), Loc.getManager())); + UnifiedSourceLoc(PLoc.getIncludeLoc(), Loc.getManager())); // Emit the inclusion text/note. emitIncludeLocation(Loc, PLoc); } /// \brief Emit the module import stack associated with the current location. -void DiagnosticRenderer::emitImportStack(FullSourceLoc Loc) { +void DiagnosticRenderer::emitImportStack(UnifiedSourceLoc Loc) { if (Loc.isInvalid()) { emitModuleBuildStack(Loc.getManager()); return; } - std::pair NextImportLoc = Loc.getModuleImportLoc(); + std::pair NextImportLoc = + Loc.getModuleImportLoc(); emitImportStackRecursively(NextImportLoc.first, NextImportLoc.second); } /// \brief Helper to recursivly walk up the import stack and print each layer /// on the way back down. -void DiagnosticRenderer::emitImportStackRecursively(FullSourceLoc Loc, +void DiagnosticRenderer::emitImportStackRecursively(UnifiedSourceLoc Loc, StringRef ModuleName) { if (ModuleName.empty()) { return; } - PresumedLoc PLoc = Loc.getPresumedLoc(DiagOpts->ShowPresumedLoc); + UnifiedPLoc PLoc = Loc.getPresumedLoc(DiagOpts->ShowPresumedLoc); // Emit the other import frames first. - std::pair NextImportLoc = Loc.getModuleImportLoc(); + std::pair NextImportLoc = + Loc.getModuleImportLoc(); emitImportStackRecursively(NextImportLoc.first, NextImportLoc.second); // Emit the inclusion text/note. @@ -339,7 +343,7 @@ // each chain. Two locations are part of the same macro expansion // iff the FileID is the same. static void -mapDiagnosticRanges(FullSourceLoc CaretLoc, ArrayRef Ranges, +mapDiagnosticRanges(UnifiedSourceLoc CaretLoc, ArrayRef Ranges, SmallVectorImpl &SpellingRanges) { FileID CaretLocFileID = CaretLoc.getFileID(); @@ -394,23 +398,24 @@ } } -void DiagnosticRenderer::emitCaret(FullSourceLoc Loc, +void DiagnosticRenderer::emitCaret(UnifiedSourceLoc Loc, DiagnosticsEngine::Level Level, ArrayRef Ranges, ArrayRef Hints) { SmallVector SpellingRanges; - mapDiagnosticRanges(Loc, Ranges, SpellingRanges); + if (!Ranges.empty()) + mapDiagnosticRanges(Loc, Ranges, SpellingRanges); emitCodeContext(Loc, Level, SpellingRanges, Hints); } /// \brief A helper function for emitMacroExpansion to print the /// macro expansion message void DiagnosticRenderer::emitSingleMacroExpansion( - FullSourceLoc Loc, DiagnosticsEngine::Level Level, + UnifiedSourceLoc Loc, DiagnosticsEngine::Level Level, ArrayRef Ranges) { // Find the spelling location for the macro definition. We must use the // spelling location here to avoid emitting a macro backtrace for the note. - FullSourceLoc SpellingLoc = Loc.getSpellingLoc(); + UnifiedSourceLoc SpellingLoc = Loc.getSpellingLoc(); // Map the ranges into the FileID of the diagnostic location. SmallVector SpellingRanges; @@ -460,7 +465,7 @@ /// A helper function to check if the current ranges are all inside the same /// macro argument expansion as Loc. -static bool checkRangesForMacroArgExpansion(FullSourceLoc Loc, +static bool checkRangesForMacroArgExpansion(UnifiedSourceLoc Loc, ArrayRef Ranges) { assert(Loc.isMacroID() && "Must be a macro expansion!"); @@ -476,7 +481,7 @@ return false; /// To store the source location of the argument location. - FullSourceLoc ArgumentLoc; + UnifiedSourceLoc ArgumentLoc; /// Set the ArgumentLoc to the beginning location of the expansion of Loc /// so to check if the ranges expands to the same beginning location. @@ -502,14 +507,14 @@ /// \param Level The diagnostic level currently being emitted. /// \param Ranges The underlined ranges for this code snippet. /// \param Hints The FixIt hints active for this diagnostic. -void DiagnosticRenderer::emitMacroExpansions(FullSourceLoc Loc, +void DiagnosticRenderer::emitMacroExpansions(UnifiedSourceLoc Loc, DiagnosticsEngine::Level Level, ArrayRef Ranges, ArrayRef Hints) { assert(Loc.isValid() && "must have a valid source location here"); // Produce a stack of macro backtraces. - SmallVector LocationStack; + SmallVector LocationStack; unsigned IgnoredEnd = 0; while (Loc.isMacroID()) { // If this is the expansion of a macro argument, point the caret at the @@ -567,8 +572,8 @@ DiagnosticNoteRenderer::~DiagnosticNoteRenderer() {} -void DiagnosticNoteRenderer::emitIncludeLocation(FullSourceLoc Loc, - PresumedLoc PLoc) { +void DiagnosticNoteRenderer::emitIncludeLocation(UnifiedSourceLoc Loc, + UnifiedPLoc PLoc) { // Generate a note indicating the include location. SmallString<200> MessageStorage; llvm::raw_svector_ostream Message(MessageStorage); @@ -577,8 +582,8 @@ emitNote(Loc, Message.str()); } -void DiagnosticNoteRenderer::emitImportLocation(FullSourceLoc Loc, - PresumedLoc PLoc, +void DiagnosticNoteRenderer::emitImportLocation(UnifiedSourceLoc Loc, + UnifiedPLoc PLoc, StringRef ModuleName) { // Generate a note indicating the include location. SmallString<200> MessageStorage; @@ -591,8 +596,8 @@ emitNote(Loc, Message.str()); } -void DiagnosticNoteRenderer::emitBuildingModuleLocation(FullSourceLoc Loc, - PresumedLoc PLoc, +void DiagnosticNoteRenderer::emitBuildingModuleLocation(UnifiedSourceLoc Loc, + UnifiedPLoc PLoc, StringRef ModuleName) { // Generate a note indicating the include location. SmallString<200> MessageStorage; Index: lib/Frontend/SerializedDiagnosticPrinter.cpp =================================================================== --- lib/Frontend/SerializedDiagnosticPrinter.cpp +++ lib/Frontend/SerializedDiagnosticPrinter.cpp @@ -63,18 +63,18 @@ ~SDiagsRenderer() override {} protected: - void emitDiagnosticMessage(FullSourceLoc Loc, PresumedLoc PLoc, + void emitDiagnosticMessage(UnifiedSourceLoc Loc, UnifiedPLoc PLoc, DiagnosticsEngine::Level Level, StringRef Message, ArrayRef Ranges, DiagOrStoredDiag D) override; - void emitDiagnosticLoc(FullSourceLoc Loc, PresumedLoc PLoc, + void emitDiagnosticLoc(UnifiedSourceLoc Loc, UnifiedPLoc PLoc, DiagnosticsEngine::Level Level, ArrayRef Ranges) override {} - void emitNote(FullSourceLoc Loc, StringRef Message) override; + void emitNote(UnifiedSourceLoc Loc, StringRef Message) override; - void emitCodeContext(FullSourceLoc Loc, DiagnosticsEngine::Level Level, + void emitCodeContext(UnifiedSourceLoc Loc, DiagnosticsEngine::Level Level, SmallVectorImpl &Ranges, ArrayRef Hints) override; @@ -653,7 +653,7 @@ } void SDiagsRenderer::emitDiagnosticMessage( - FullSourceLoc Loc, PresumedLoc PLoc, DiagnosticsEngine::Level Level, + UnifiedSourceLoc Loc, UnifiedPLoc PLoc, DiagnosticsEngine::Level Level, StringRef Message, ArrayRef Ranges, DiagOrStoredDiag D) { Writer.EmitDiagnosticMessage(Loc, PLoc, Level, Message, D); @@ -709,14 +709,14 @@ } } -void SDiagsRenderer::emitCodeContext(FullSourceLoc Loc, +void SDiagsRenderer::emitCodeContext(UnifiedSourceLoc Loc, DiagnosticsEngine::Level Level, SmallVectorImpl &Ranges, ArrayRef Hints) { Writer.EmitCodeContext(Ranges, Hints, Loc.getManager()); } -void SDiagsRenderer::emitNote(FullSourceLoc Loc, StringRef Message) { +void SDiagsRenderer::emitNote(UnifiedSourceLoc Loc, StringRef Message) { Writer.EnterDiagBlock(); PresumedLoc PLoc = Loc.hasManager() ? Loc.getPresumedLoc() : PresumedLoc(); Writer.EmitDiagnosticMessage(Loc, PLoc, DiagnosticsEngine::Note, Message, Index: lib/Frontend/TextDiagnostic.cpp =================================================================== --- lib/Frontend/TextDiagnostic.cpp +++ lib/Frontend/TextDiagnostic.cpp @@ -673,7 +673,7 @@ TextDiagnostic::~TextDiagnostic() {} void TextDiagnostic::emitDiagnosticMessage( - FullSourceLoc Loc, PresumedLoc PLoc, DiagnosticsEngine::Level Level, + UnifiedSourceLoc Loc, UnifiedPLoc PLoc, DiagnosticsEngine::Level Level, StringRef Message, ArrayRef Ranges, DiagOrStoredDiag D) { uint64_t StartOfLocationInfo = OS.tell(); @@ -761,13 +761,13 @@ OS << '\n'; } -void TextDiagnostic::emitFilename(StringRef Filename, const SourceManager &SM) { +void TextDiagnostic::emitFilename(StringRef Filename, const SourceManager *SM) { SmallVector AbsoluteFilename; - if (DiagOpts->AbsolutePath) { - const DirectoryEntry *Dir = SM.getFileManager().getDirectory( + if (SM && DiagOpts->AbsolutePath) { + const DirectoryEntry *Dir = SM->getFileManager().getDirectory( llvm::sys::path::parent_path(Filename)); if (Dir) { - StringRef DirName = SM.getFileManager().getCanonicalName(Dir); + StringRef DirName = SM->getFileManager().getCanonicalName(Dir); llvm::sys::path::append(AbsoluteFilename, DirName, llvm::sys::path::filename(Filename)); Filename = StringRef(AbsoluteFilename.data(), AbsoluteFilename.size()); @@ -783,7 +783,7 @@ /// This includes extracting as much location information as is present for /// the diagnostic and printing it, as well as any include stack or source /// ranges necessary. -void TextDiagnostic::emitDiagnosticLoc(FullSourceLoc Loc, PresumedLoc PLoc, +void TextDiagnostic::emitDiagnosticLoc(UnifiedSourceLoc Loc, UnifiedPLoc PLoc, DiagnosticsEngine::Level Level, ArrayRef Ranges) { if (PLoc.isInvalid()) { @@ -792,7 +792,7 @@ if (FID.isValid()) { const FileEntry *FE = Loc.getFileEntry(); if (FE && FE->isValid()) { - emitFilename(FE->getName(), Loc.getManager()); + emitFilename(FE->getName(), &Loc.getManager()); if (FE->isInPCH()) OS << " (in PCH)"; OS << ": "; @@ -808,7 +808,8 @@ if (DiagOpts->ShowColors) OS.changeColor(savedColor, true); - emitFilename(PLoc.getFilename(), Loc.getManager()); + emitFilename(PLoc.getFilename(), + Loc.hasManager() ? &Loc.getManager() : nullptr); switch (DiagOpts->getFormat()) { case DiagnosticOptions::Clang: OS << ':' << LineNo; break; case DiagnosticOptions::MSVC: OS << '(' << LineNo; break; @@ -852,10 +853,10 @@ // Ignore invalid ranges. if (!RI->isValid()) continue; - FullSourceLoc B = - FullSourceLoc(RI->getBegin(), Loc.getManager()).getExpansionLoc(); - FullSourceLoc E = - FullSourceLoc(RI->getEnd(), Loc.getManager()).getExpansionLoc(); + UnifiedSourceLoc B = + UnifiedSourceLoc(RI->getBegin(), Loc.getManager()).getExpansionLoc(); + UnifiedSourceLoc E = + UnifiedSourceLoc(RI->getEnd(), Loc.getManager()).getExpansionLoc(); // If the End location and the start location are the same and are a // macro location, then the range was something that came from a @@ -863,7 +864,7 @@ // best we can do is to highlight the range. If this is a // function-like macro, we'd also like to highlight the arguments. if (B == E && RI->getEnd().isMacroID()) - E = FullSourceLoc(RI->getEnd(), Loc.getManager()) + E = UnifiedSourceLoc(RI->getEnd(), Loc.getManager()) .getExpansionRange() .second; @@ -892,7 +893,8 @@ OS << ' '; } -void TextDiagnostic::emitIncludeLocation(FullSourceLoc Loc, PresumedLoc PLoc) { +void TextDiagnostic::emitIncludeLocation(UnifiedSourceLoc Loc, + UnifiedPLoc PLoc) { if (DiagOpts->ShowLocation && PLoc.isValid()) OS << "In file included from " << PLoc.getFilename() << ':' << PLoc.getLine() << ":\n"; @@ -900,7 +902,7 @@ OS << "In included file:\n"; } -void TextDiagnostic::emitImportLocation(FullSourceLoc Loc, PresumedLoc PLoc, +void TextDiagnostic::emitImportLocation(UnifiedSourceLoc Loc, UnifiedPLoc PLoc, StringRef ModuleName) { if (DiagOpts->ShowLocation && PLoc.isValid()) OS << "In module '" << ModuleName << "' imported from " @@ -909,8 +911,8 @@ OS << "In module '" << ModuleName << "':\n"; } -void TextDiagnostic::emitBuildingModuleLocation(FullSourceLoc Loc, - PresumedLoc PLoc, +void TextDiagnostic::emitBuildingModuleLocation(UnifiedSourceLoc Loc, + UnifiedPLoc PLoc, StringRef ModuleName) { if (DiagOpts->ShowLocation && PLoc.isValid()) OS << "While building module '" << ModuleName << "' imported from " @@ -1072,7 +1074,7 @@ /// \param Ranges The underlined ranges for this code snippet. /// \param Hints The FixIt hints active for this diagnostic. void TextDiagnostic::emitSnippetAndCaret( - FullSourceLoc Loc, DiagnosticsEngine::Level Level, + UnifiedSourceLoc Loc, DiagnosticsEngine::Level Level, SmallVectorImpl &Ranges, ArrayRef Hints) { assert(Loc.isValid() && "must have a valid source location here"); assert(Loc.isFileID() && "must have a file location here"); @@ -1085,9 +1087,11 @@ // multiple times if one loc has multiple diagnostics. if (!DiagOpts->ShowCarets) return; + if (Loc == LastLoc && Ranges.empty() && Hints.empty() && - (LastLevel != DiagnosticsEngine::Note || Level == LastLevel)) + (LastLevel != DiagnosticsEngine::Note || Level == LastLevel)) { return; + } // Decompose the location into a FID/Offset pair. std::pair LocInfo = Loc.getDecomposedLoc(); @@ -1153,8 +1157,10 @@ CaretLine.resize(ColNo+1, ' '); CaretLine[ColNo] = '^'; - std::string FixItInsertionLine = buildFixItInsertionLine( - LineNo, sourceColMap, Hints, Loc.getManager(), DiagOpts.get()); + std::string FixItInsertionLine; + if (!Hints.empty()) + FixItInsertionLine = buildFixItInsertionLine( + LineNo, sourceColMap, Hints, Loc.getManager(), DiagOpts.get()); // If the source line is too long for our terminal, select only the // "interesting" source region within that line. @@ -1197,7 +1203,8 @@ } // Print out any parseable fixit information requested by the options. - emitParseableFixits(Hints, Loc.getManager()); + if (!Hints.empty()) + emitParseableFixits(Hints, Loc.getManager()); } void TextDiagnostic::emitSnippet(StringRef line) { @@ -1265,7 +1272,7 @@ // We specifically do not do word-wrapping or tab-expansion here, // because this is supposed to be easy to parse. - PresumedLoc PLoc = SM.getPresumedLoc(BLoc); + UnifiedPLoc PLoc = SM.getPresumedLoc(BLoc); if (PLoc.isInvalid()) break; Index: lib/Frontend/TextDiagnosticPrinter.cpp =================================================================== --- lib/Frontend/TextDiagnosticPrinter.cpp +++ lib/Frontend/TextDiagnosticPrinter.cpp @@ -146,13 +146,9 @@ // Assert that the rest of our infrastructure is setup properly. assert(DiagOpts && "Unexpected diagnostic without options set"); - assert(Info.hasSourceManager() && - "Unexpected diagnostic with no source manager"); assert(TextDiag && "Unexpected diagnostic outside source file processing"); - TextDiag->emitDiagnostic( - FullSourceLoc(Info.getLocation(), Info.getSourceManager()), Level, - DiagMessageStream.str(), Info.getRanges(), Info.getFixItHints()); - + TextDiag->emitDiagnostic(Info.getLocation(), Level, DiagMessageStream.str(), + Info.getRanges(), Info.getFixItHints()); OS.flush(); } Index: test/Driver/asm-diags.s =================================================================== --- /dev/null +++ test/Driver/asm-diags.s @@ -0,0 +1,23 @@ +# RUN: not %clang --target=arm-linux-gnueabi -march=armv8-m.main -c %s 2>&1 | FileCheck %s +# RUN: not %clang --target=arm-linux-gnueabi -march=armv8-m.main -w -c %s 2>&1 | FileCheck %s --check-prefix=CHECK-NO-WARNINGS +# RUN: not %clang --target=arm-linux-gnueabi -march=armv8-m.main -Werror -c %s 2>&1 | FileCheck %s --check-prefix=CHECK-FATAL-WARNINGS + +.thumb + ADD r0, r0, #0xFFFF0001 + LDM r0, {r1, r0} + +# CHECK: asm-diags.s:6:14: error: +# CHECK: ADD r0, r0, #0xFFFF0001 +# CHECK: asm-diags.s:7:15: warning: +# CHECK: LDM r0, {r1, r0} +# CHECK: 1 warning and 1 error generated. + +# CHECK-NO-WARNINGS: asm-diags.s:6:14: error: +# CHECK-NO-WARNINGS: ADD r0, r0, #0xFFFF0001 +# CHECK-NO-WARNINGS: 1 error generated. + +# CHECK-FATAL-WARNINGS: asm-diags.s:6:14: error: +# CHECK-FATAL-WARNINGS: ADD r0, r0, #0xFFFF0001 +# CHECK-FATAL-WARNINGS: asm-diags.s:7:15: error: +# CHECK-FATAL-WARNINGS: LDM r0, {r1, r0} +# CHECK-FATAL-WARNINGS: 2 errors generated. Index: tools/driver/cc1as_main.cpp =================================================================== --- tools/driver/cc1as_main.cpp +++ tools/driver/cc1as_main.cpp @@ -14,6 +14,10 @@ #include "clang/Basic/Diagnostic.h" #include "clang/Basic/DiagnosticOptions.h" +#include "clang/Basic/FileManager.h" +#include "clang/Basic/FileSystemOptions.h" +#include "clang/Basic/LangOptions.h" +#include "clang/Basic/SourceManager.h" #include "clang/Driver/DriverDiagnostic.h" #include "clang/Driver/Options.h" #include "clang/Frontend/DiagnosticOptions.h" @@ -46,6 +50,7 @@ #include "llvm/Support/Host.h" #include "llvm/Support/MemoryBuffer.h" #include "llvm/Support/Path.h" +#include "llvm/Support/Process.h" #include "llvm/Support/Signals.h" #include "llvm/Support/SourceMgr.h" #include "llvm/Support/TargetRegistry.h" @@ -284,6 +289,29 @@ return Out; } +struct DiagsHandlerContext { + DiagnosticsEngine &Diags; + const SourceMgr *SrcMgr; +}; + +static void AssemblerDiagsHandler(const SMDiagnostic &D, void *Context) { + auto &Diags = *static_cast(Context); + 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; + } + + Diags.Report(D.getSourceMgr(), D.getLoc(), DiagID) << D.getMessage(); +} + static bool ExecuteAssembler(AssemblerInvocation &Opts, DiagnosticsEngine &Diags) { // Get the target specific parser. @@ -309,6 +337,8 @@ // it later. SrcMgr.setIncludeDirs(Opts.IncludePaths); + SrcMgr.setDiagHandler(AssemblerDiagsHandler, &Diags); + std::unique_ptr MRI(TheTarget->createMCRegInfo(Opts.Triple)); assert(MRI && "Unable to create target register info!"); @@ -475,7 +505,6 @@ IntrusiveRefCntPtr DiagOpts = new DiagnosticOptions(); TextDiagnosticPrinter *DiagClient = new TextDiagnosticPrinter(errs(), &*DiagOpts); - DiagClient->setPrefix("clang -cc1as"); IntrusiveRefCntPtr DiagID(new DiagnosticIDs()); DiagnosticsEngine Diags(DiagID, &*DiagOpts, DiagClient); @@ -517,9 +546,35 @@ llvm::cl::ParseCommandLineOptions(NumArgs + 1, Args); } + ProcessWarningOptions(Diags, Diags.getDiagnosticOptions(), true); + + LangOptions LangOpts; + DiagClient->BeginSourceFile(LangOpts, nullptr); + // Execute the invocation, unless there were parsing errors. bool Failed = Diags.hasErrorOccurred() || ExecuteAssembler(Asm, Diags); + DiagClient->EndSourceFile(); + + // Notify the diagnostic client that all files were processed. + Diags.getClient()->finish(); + + if (Diags.getDiagnosticOptions().ShowCarets) { + // We can have multiple diagnostics sharing one diagnostic client. + // Get the total number of warnings/errors from the client. + unsigned NumWarnings = Diags.getClient()->getNumWarnings(); + unsigned NumErrors = Diags.getClient()->getNumErrors(); + + if (NumWarnings) + errs() << NumWarnings << " warning" << (NumWarnings == 1 ? "" : "s"); + if (NumWarnings && NumErrors) + errs() << " and "; + if (NumErrors) + errs() << NumErrors << " error" << (NumErrors == 1 ? "" : "s"); + if (NumWarnings || NumErrors) + errs() << " generated.\n"; + } + // If any timers were active but haven't been destroyed yet, print their // results now. TimerGroup::printAll(errs()); Index: tools/libclang/CIndexDiagnostic.cpp =================================================================== --- tools/libclang/CIndexDiagnostic.cpp +++ tools/libclang/CIndexDiagnostic.cpp @@ -110,7 +110,7 @@ CurrentSet = &CD.getChildDiagnostics(); } - void emitDiagnosticMessage(FullSourceLoc Loc, PresumedLoc PLoc, + void emitDiagnosticMessage(UnifiedSourceLoc Loc, UnifiedPLoc PLoc, DiagnosticsEngine::Level Level, StringRef Message, ArrayRef Ranges, DiagOrStoredDiag D) override { @@ -126,15 +126,15 @@ llvm::make_unique(Message, L)); } - void emitDiagnosticLoc(FullSourceLoc Loc, PresumedLoc PLoc, + void emitDiagnosticLoc(UnifiedSourceLoc Loc, UnifiedPLoc PLoc, DiagnosticsEngine::Level Level, ArrayRef Ranges) override {} - void emitCodeContext(FullSourceLoc Loc, DiagnosticsEngine::Level Level, + void emitCodeContext(UnifiedSourceLoc Loc, DiagnosticsEngine::Level Level, SmallVectorImpl &Ranges, ArrayRef Hints) override {} - void emitNote(FullSourceLoc Loc, StringRef Message) override { + void emitNote(UnifiedSourceLoc Loc, StringRef Message) override { CXSourceLocation L; if (Loc.hasManager()) L = translateSourceLocation(Loc.getManager(), LangOpts, Loc);