diff --git a/clang/include/clang/Analysis/PathDiagnostic.h b/clang/include/clang/Analysis/PathDiagnostic.h --- a/clang/include/clang/Analysis/PathDiagnostic.h +++ b/clang/include/clang/Analysis/PathDiagnostic.h @@ -46,10 +46,15 @@ class Decl; class Expr; class LocationContext; +class MacroExpansionContext; class MemberExpr; class ProgramPoint; class SourceManager; +namespace cross_tu { +class CrossTranslationUnitContext; +} // namespace cross_tu + namespace ento { //===----------------------------------------------------------------------===// @@ -903,6 +908,12 @@ void FullProfile(llvm::FoldingSetNodeID &ID) const; }; +void createHTMLSingleFileDiagnosticConsumer( + PathDiagnosticConsumerOptions DiagOpts, + std::vector &C, const std::string &OutputDir, + const Preprocessor &PP, + const clang::cross_tu::CrossTranslationUnitContext &CTU, + const clang::MacroExpansionContext &MacroExpansions); } // namespace ento } // namespace clang diff --git a/clang/include/clang/StaticAnalyzer/Core/PathDiagnosticConsumers.h b/clang/include/clang/StaticAnalyzer/Core/PathDiagnosticConsumers.h --- a/clang/include/clang/StaticAnalyzer/Core/PathDiagnosticConsumers.h +++ b/clang/include/clang/StaticAnalyzer/Core/PathDiagnosticConsumers.h @@ -21,7 +21,9 @@ namespace clang { class AnalyzerOptions; +class MacroExpansionContext; class Preprocessor; + namespace cross_tu { class CrossTranslationUnitContext; } @@ -35,7 +37,8 @@ void CREATEFN(PathDiagnosticConsumerOptions Diagopts, \ PathDiagnosticConsumers &C, const std::string &Prefix, \ const Preprocessor &PP, \ - const cross_tu::CrossTranslationUnitContext &CTU); + const cross_tu::CrossTranslationUnitContext &CTU, \ + const MacroExpansionContext &MacroExpansions); #include "clang/StaticAnalyzer/Core/Analyses.def" } // end 'ento' namespace diff --git a/clang/lib/StaticAnalyzer/Core/HTMLDiagnostics.cpp b/clang/lib/StaticAnalyzer/Core/HTMLDiagnostics.cpp --- a/clang/lib/StaticAnalyzer/Core/HTMLDiagnostics.cpp +++ b/clang/lib/StaticAnalyzer/Core/HTMLDiagnostics.cpp @@ -10,11 +10,12 @@ // //===----------------------------------------------------------------------===// -#include "clang/Analysis/IssueHash.h" -#include "clang/Analysis/PathDiagnostic.h" #include "clang/AST/Decl.h" #include "clang/AST/DeclBase.h" #include "clang/AST/Stmt.h" +#include "clang/Analysis/IssueHash.h" +#include "clang/Analysis/MacroExpansionContext.h" +#include "clang/Analysis/PathDiagnostic.h" #include "clang/Basic/FileManager.h" #include "clang/Basic/LLVM.h" #include "clang/Basic/SourceLocation.h" @@ -135,14 +136,16 @@ void ento::createHTMLDiagnosticConsumer( PathDiagnosticConsumerOptions DiagOpts, PathDiagnosticConsumers &C, const std::string &OutputDir, const Preprocessor &PP, - const cross_tu::CrossTranslationUnitContext &CTU) { + const cross_tu::CrossTranslationUnitContext &CTU, + const MacroExpansionContext &MacroExpansions) { // FIXME: HTML is currently our default output type, but if the output // directory isn't specified, it acts like if it was in the minimal text // output mode. This doesn't make much sense, we should have the minimal text // as our default. In the case of backward compatibility concerns, this could // be preserved with -analyzer-config-compatibility-mode=true. - createTextMinimalPathDiagnosticConsumer(DiagOpts, C, OutputDir, PP, CTU); + createTextMinimalPathDiagnosticConsumer(DiagOpts, C, OutputDir, PP, CTU, + MacroExpansions); // TODO: Emit an error here. if (OutputDir.empty()) @@ -154,8 +157,10 @@ void ento::createHTMLSingleFileDiagnosticConsumer( PathDiagnosticConsumerOptions DiagOpts, PathDiagnosticConsumers &C, const std::string &OutputDir, const Preprocessor &PP, - const cross_tu::CrossTranslationUnitContext &CTU) { - createTextMinimalPathDiagnosticConsumer(DiagOpts, C, OutputDir, PP, CTU); + const cross_tu::CrossTranslationUnitContext &CTU, + const clang::MacroExpansionContext &MacroExpansions) { + createTextMinimalPathDiagnosticConsumer(DiagOpts, C, OutputDir, PP, CTU, + MacroExpansions); // TODO: Emit an error here. if (OutputDir.empty()) @@ -167,13 +172,15 @@ void ento::createPlistHTMLDiagnosticConsumer( PathDiagnosticConsumerOptions DiagOpts, PathDiagnosticConsumers &C, const std::string &prefix, const Preprocessor &PP, - const cross_tu::CrossTranslationUnitContext &CTU) { + const cross_tu::CrossTranslationUnitContext &CTU, + const MacroExpansionContext &MacroExpansions) { createHTMLDiagnosticConsumer( - DiagOpts, C, std::string(llvm::sys::path::parent_path(prefix)), PP, - CTU); - createPlistMultiFileDiagnosticConsumer(DiagOpts, C, prefix, PP, CTU); + DiagOpts, C, std::string(llvm::sys::path::parent_path(prefix)), PP, CTU, + MacroExpansions); + createPlistMultiFileDiagnosticConsumer(DiagOpts, C, prefix, PP, CTU, + MacroExpansions); createTextMinimalPathDiagnosticConsumer(std::move(DiagOpts), C, prefix, PP, - CTU); + CTU, MacroExpansions); } //===----------------------------------------------------------------------===// diff --git a/clang/lib/StaticAnalyzer/Core/PlistDiagnostics.cpp b/clang/lib/StaticAnalyzer/Core/PlistDiagnostics.cpp --- a/clang/lib/StaticAnalyzer/Core/PlistDiagnostics.cpp +++ b/clang/lib/StaticAnalyzer/Core/PlistDiagnostics.cpp @@ -11,6 +11,7 @@ //===----------------------------------------------------------------------===// #include "clang/Analysis/IssueHash.h" +#include "clang/Analysis/MacroExpansionContext.h" #include "clang/Analysis/PathDiagnostic.h" #include "clang/Basic/FileManager.h" #include "clang/Basic/PlistSupport.h" @@ -43,6 +44,7 @@ const std::string OutputFile; const Preprocessor &PP; const cross_tu::CrossTranslationUnitContext &CTU; + const MacroExpansionContext &MacroExpansions; const bool SupportsCrossFileDiagnostics; void printBugPath(llvm::raw_ostream &o, const FIDMap &FM, @@ -52,6 +54,7 @@ PlistDiagnostics(PathDiagnosticConsumerOptions DiagOpts, const std::string &OutputFile, const Preprocessor &PP, const cross_tu::CrossTranslationUnitContext &CTU, + const MacroExpansionContext &MacroExpansions, bool supportsMultipleFiles); ~PlistDiagnostics() override {} @@ -80,14 +83,14 @@ const FIDMap& FM; const Preprocessor &PP; const cross_tu::CrossTranslationUnitContext &CTU; + const MacroExpansionContext &MacroExpansions; llvm::SmallVector MacroPieces; public: - PlistPrinter(const FIDMap& FM, - const Preprocessor &PP, - const cross_tu::CrossTranslationUnitContext &CTU) - : FM(FM), PP(PP), CTU(CTU) { - } + PlistPrinter(const FIDMap &FM, const Preprocessor &PP, + const cross_tu::CrossTranslationUnitContext &CTU, + const MacroExpansionContext &MacroExpansions) + : FM(FM), PP(PP), CTU(CTU), MacroExpansions(MacroExpansions) {} void ReportDiag(raw_ostream &o, const PathDiagnosticPiece& P) { ReportPiece(o, P, /*indent*/ 4, /*depth*/ 0, /*includeControlFlow*/ true); @@ -522,8 +525,9 @@ PlistDiagnostics::PlistDiagnostics( PathDiagnosticConsumerOptions DiagOpts, const std::string &output, const Preprocessor &PP, const cross_tu::CrossTranslationUnitContext &CTU, - bool supportsMultipleFiles) + const MacroExpansionContext &MacroExpansions, bool supportsMultipleFiles) : DiagOpts(std::move(DiagOpts)), OutputFile(output), PP(PP), CTU(CTU), + MacroExpansions(MacroExpansions), SupportsCrossFileDiagnostics(supportsMultipleFiles) { // FIXME: Will be used by a later planned change. (void)this->CTU; @@ -532,36 +536,40 @@ void ento::createPlistDiagnosticConsumer( PathDiagnosticConsumerOptions DiagOpts, PathDiagnosticConsumers &C, const std::string &OutputFile, const Preprocessor &PP, - const cross_tu::CrossTranslationUnitContext &CTU) { + const cross_tu::CrossTranslationUnitContext &CTU, + const MacroExpansionContext &MacroExpansions) { // TODO: Emit an error here. if (OutputFile.empty()) return; C.push_back(new PlistDiagnostics(DiagOpts, OutputFile, PP, CTU, + MacroExpansions, /*supportsMultipleFiles=*/false)); createTextMinimalPathDiagnosticConsumer(std::move(DiagOpts), C, OutputFile, - PP, CTU); + PP, CTU, MacroExpansions); } void ento::createPlistMultiFileDiagnosticConsumer( PathDiagnosticConsumerOptions DiagOpts, PathDiagnosticConsumers &C, const std::string &OutputFile, const Preprocessor &PP, - const cross_tu::CrossTranslationUnitContext &CTU) { + const cross_tu::CrossTranslationUnitContext &CTU, + const MacroExpansionContext &MacroExpansions) { // TODO: Emit an error here. if (OutputFile.empty()) return; C.push_back(new PlistDiagnostics(DiagOpts, OutputFile, PP, CTU, + MacroExpansions, /*supportsMultipleFiles=*/true)); createTextMinimalPathDiagnosticConsumer(std::move(DiagOpts), C, OutputFile, - PP, CTU); + PP, CTU, MacroExpansions); } void PlistDiagnostics::printBugPath(llvm::raw_ostream &o, const FIDMap &FM, const PathPieces &Path) { - PlistPrinter Printer(FM, PP, CTU); + PlistPrinter Printer(FM, PP, CTU, MacroExpansions); assert(std::is_partitioned(Path.begin(), Path.end(), [](const PathDiagnosticPieceRef &E) { return E->getKind() == PathDiagnosticPiece::Note; diff --git a/clang/lib/StaticAnalyzer/Core/SarifDiagnostics.cpp b/clang/lib/StaticAnalyzer/Core/SarifDiagnostics.cpp --- a/clang/lib/StaticAnalyzer/Core/SarifDiagnostics.cpp +++ b/clang/lib/StaticAnalyzer/Core/SarifDiagnostics.cpp @@ -10,6 +10,7 @@ // //===----------------------------------------------------------------------===// +#include "clang/Analysis/MacroExpansionContext.h" #include "clang/Analysis/PathDiagnostic.h" #include "clang/Basic/FileManager.h" #include "clang/Basic/Version.h" @@ -48,7 +49,8 @@ void ento::createSarifDiagnosticConsumer( PathDiagnosticConsumerOptions DiagOpts, PathDiagnosticConsumers &C, const std::string &Output, const Preprocessor &PP, - const cross_tu::CrossTranslationUnitContext &CTU) { + const cross_tu::CrossTranslationUnitContext &CTU, + const MacroExpansionContext &MacroExpansions) { // TODO: Emit an error here. if (Output.empty()) @@ -56,7 +58,7 @@ C.push_back(new SarifDiagnostics(Output, PP.getLangOpts())); createTextMinimalPathDiagnosticConsumer(std::move(DiagOpts), C, Output, PP, - CTU); + CTU, MacroExpansions); } static StringRef getFileName(const FileEntry &FE) { diff --git a/clang/lib/StaticAnalyzer/Core/TextDiagnostics.cpp b/clang/lib/StaticAnalyzer/Core/TextDiagnostics.cpp --- a/clang/lib/StaticAnalyzer/Core/TextDiagnostics.cpp +++ b/clang/lib/StaticAnalyzer/Core/TextDiagnostics.cpp @@ -10,6 +10,7 @@ // //===----------------------------------------------------------------------===// +#include "clang/Analysis/MacroExpansionContext.h" #include "clang/Analysis/PathDiagnostic.h" #include "clang/Basic/SourceManager.h" #include "clang/Basic/Version.h" @@ -138,8 +139,9 @@ void ento::createTextPathDiagnosticConsumer( PathDiagnosticConsumerOptions DiagOpts, PathDiagnosticConsumers &C, - const std::string &Prefix, const clang::Preprocessor &PP, - const cross_tu::CrossTranslationUnitContext &CTU) { + const std::string &Prefix, const Preprocessor &PP, + const cross_tu::CrossTranslationUnitContext &CTU, + const MacroExpansionContext &MacroExpansions) { C.emplace_back(new TextDiagnostics(std::move(DiagOpts), PP.getDiagnostics(), PP.getLangOpts(), /*ShouldDisplayPathNotes=*/true)); @@ -147,8 +149,9 @@ void ento::createTextMinimalPathDiagnosticConsumer( PathDiagnosticConsumerOptions DiagOpts, PathDiagnosticConsumers &C, - const std::string &Prefix, const clang::Preprocessor &PP, - const cross_tu::CrossTranslationUnitContext &CTU) { + const std::string &Prefix, const Preprocessor &PP, + const cross_tu::CrossTranslationUnitContext &CTU, + const MacroExpansionContext &MacroExpansions) { C.emplace_back(new TextDiagnostics(std::move(DiagOpts), PP.getDiagnostics(), PP.getLangOpts(), /*ShouldDisplayPathNotes=*/false)); diff --git a/clang/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp b/clang/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp --- a/clang/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp +++ b/clang/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp @@ -20,6 +20,7 @@ #include "clang/Analysis/CFG.h" #include "clang/Analysis/CallGraph.h" #include "clang/Analysis/CodeInjector.h" +#include "clang/Analysis/MacroExpansionContext.h" #include "clang/Analysis/PathDiagnostic.h" #include "clang/Basic/SourceManager.h" #include "clang/CrossTU/CrossTranslationUnit.h" @@ -98,6 +99,8 @@ /// working with a PCH file. SetOfDecls LocalTUDecls; + MacroExpansionContext MacroExpansions; + // Set of PathDiagnosticConsumers. Owned by AnalysisManager. PathDiagnosticConsumers PathConsumers; @@ -122,7 +125,8 @@ CodeInjector *injector) : RecVisitorMode(0), RecVisitorBR(nullptr), Ctx(nullptr), PP(CI.getPreprocessor()), OutDir(outdir), Opts(std::move(opts)), - Plugins(plugins), Injector(injector), CTU(CI) { + Plugins(plugins), Injector(injector), CTU(CI), + MacroExpansions(PP, CI.getLangOpts()) { DigestAnalyzerOptions(); if (Opts->PrintStats || Opts->ShouldSerializeStats) { AnalyzerTimers = std::make_unique( @@ -150,7 +154,8 @@ break; #define ANALYSIS_DIAGNOSTICS(NAME, CMDFLAG, DESC, CREATEFN) \ case PD_##NAME: \ - CREATEFN(Opts->getDiagOpts(), PathConsumers, OutDir, PP, CTU); \ + CREATEFN(Opts->getDiagOpts(), PathConsumers, OutDir, PP, CTU, \ + MacroExpansions); \ break; #include "clang/StaticAnalyzer/Core/Analyses.def" default: