Index: clang-tidy/ClangTidy.cpp =================================================================== --- clang-tidy/ClangTidy.cpp +++ clang-tidy/ClangTidy.cpp @@ -551,7 +551,9 @@ Context.setProfileStoragePrefix(StoreCheckProfile); ClangTidyDiagnosticConsumer DiagConsumer(Context); - + DiagnosticsEngine DE(new DiagnosticIDs(), new DiagnosticOptions(), + &DiagConsumer, /*ShouldOwnClient=*/false); + Context.setDiagnosticsEngine(&DE); Tool.setDiagnosticConsumer(&DiagConsumer); class ActionFactory : public FrontendActionFactory { Index: clang-tidy/ClangTidyDiagnosticConsumer.h =================================================================== --- clang-tidy/ClangTidyDiagnosticConsumer.h +++ clang-tidy/ClangTidyDiagnosticConsumer.h @@ -102,6 +102,12 @@ /// \brief Initializes \c ClangTidyContext instance. ClangTidyContext(std::unique_ptr OptionsProvider, bool AllowEnablingAnalyzerAlphaCheckers = false); + /// Sets the DiagnosticsEngine that diag() will emit diagnostics to. + // FIXME: this is required initialization, and should be a constructor param. + // Fix the context -> diag engine -> consumer -> context initialization cycle. + void setDiagnosticsEngine(DiagnosticsEngine *DiagEngine) { + this->DiagEngine = DiagEngine; + } ~ClangTidyContext(); @@ -186,9 +192,8 @@ } private: - // Sets DiagEngine and Errors. + // Writes to Stats. friend class ClangTidyDiagnosticConsumer; - friend class ClangTidyPluginAction; DiagnosticsEngine *DiagEngine; std::unique_ptr OptionsProvider; @@ -242,12 +247,11 @@ /// \brief Updates \c LastErrorRelatesToUserCode and LastErrorPassesLineFilter /// according to the diagnostic \p Location. - void checkFilters(SourceLocation Location); + void checkFilters(SourceLocation Location, const SourceManager& Sources); bool passesLineFilter(StringRef FileName, unsigned LineNumber) const; ClangTidyContext &Context; bool RemoveIncompatibleErrors; - std::unique_ptr Diags; std::vector Errors; std::unique_ptr HeaderFilter; bool LastErrorRelatesToUserCode; Index: clang-tidy/ClangTidyDiagnosticConsumer.cpp =================================================================== --- clang-tidy/ClangTidyDiagnosticConsumer.cpp +++ clang-tidy/ClangTidyDiagnosticConsumer.cpp @@ -267,13 +267,7 @@ ClangTidyContext &Ctx, bool RemoveIncompatibleErrors) : Context(Ctx), RemoveIncompatibleErrors(RemoveIncompatibleErrors), LastErrorRelatesToUserCode(false), LastErrorPassesLineFilter(false), - LastErrorWasIgnored(false) { - IntrusiveRefCntPtr DiagOpts = new DiagnosticOptions(); - Diags = llvm::make_unique( - IntrusiveRefCntPtr(new DiagnosticIDs), &*DiagOpts, this, - /*ShouldOwnClient=*/false); - Context.DiagEngine = Diags.get(); -} + LastErrorWasIgnored(false) {} void ClangTidyDiagnosticConsumer::finalizeLastError() { if (!Errors.empty()) { @@ -391,7 +385,7 @@ if (Info.getLocation().isValid() && DiagLevel != DiagnosticsEngine::Error && DiagLevel != DiagnosticsEngine::Fatal && - LineIsMarkedWithNOLINTinMacro(Diags->getSourceManager(), + LineIsMarkedWithNOLINTinMacro(Info.getSourceManager(), Info.getLocation(), Info.getID(), Context)) { ++Context.Stats.ErrorsIgnoredNOLINT; @@ -453,14 +447,14 @@ Errors.back()); SmallString<100> Message; Info.FormatDiagnostic(Message); - FullSourceLoc Loc = - (Info.getLocation().isInvalid()) - ? FullSourceLoc() - : FullSourceLoc(Info.getLocation(), Info.getSourceManager()); + FullSourceLoc Loc; + if (Info.getLocation().isValid() && Info.hasSourceManager()) + Loc = FullSourceLoc(Info.getLocation(), Info.getSourceManager()); Converter.emitDiagnostic(Loc, DiagLevel, Message, Info.getRanges(), Info.getFixItHints()); - checkFilters(Info.getLocation()); + if (Info.hasSourceManager()) + checkFilters(Info.getLocation(), Info.getSourceManager()); } bool ClangTidyDiagnosticConsumer::passesLineFilter(StringRef FileName, @@ -481,7 +475,8 @@ return false; } -void ClangTidyDiagnosticConsumer::checkFilters(SourceLocation Location) { +void ClangTidyDiagnosticConsumer::checkFilters(SourceLocation Location, + const SourceManager &Sources) { // Invalid location may mean a diagnostic in a command line, don't skip these. if (!Location.isValid()) { LastErrorRelatesToUserCode = true; @@ -489,7 +484,6 @@ return; } - const SourceManager &Sources = Diags->getSourceManager(); if (!*Context.getOptions().SystemHeaders && Sources.isInSystemHeader(Location)) return; Index: clang-tidy/plugin/ClangTidyPlugin.cpp =================================================================== --- clang-tidy/plugin/ClangTidyPlugin.cpp +++ clang-tidy/plugin/ClangTidyPlugin.cpp @@ -35,7 +35,7 @@ std::unique_ptr CreateASTConsumer(CompilerInstance &Compiler, StringRef File) override { // Insert the current diagnostics engine. - Context->DiagEngine = &Compiler.getDiagnostics(); + Context->setDiagnosticsEngine(&Compiler.getDiagnostics()); // Create the AST consumer. ClangTidyASTConsumerFactory Factory(*Context); Index: unittests/clang-tidy/ClangTidyTest.h =================================================================== --- unittests/clang-tidy/ClangTidyTest.h +++ unittests/clang-tidy/ClangTidyTest.h @@ -83,6 +83,9 @@ ClangTidyContext Context(llvm::make_unique( ClangTidyGlobalOptions(), Options)); ClangTidyDiagnosticConsumer DiagConsumer(Context); + DiagnosticsEngine DE(new DiagnosticIDs(), new DiagnosticOptions, + &DiagConsumer, false); + Context.setDiagnosticsEngine(&DE); std::vector Args(1, "clang-tidy"); Args.push_back("-fsyntax-only");