[clang] [clang][analyzer] Add plist macro formatting (PR #156046)
via cfe-commits
cfe-commits at lists.llvm.org
Fri Aug 29 08:22:33 PDT 2025
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-clang-static-analyzer-1
Author: None (ankurkraj)
<details>
<summary>Changes</summary>
Fixes [Issue#<!-- -->154743](https://github.com/llvm/llvm-project/issues/154743)
---
Full diff: https://github.com/llvm/llvm-project/pull/156046.diff
5 Files Affected:
- (modified) clang/include/clang/Analysis/PathDiagnostic.h (+5)
- (modified) clang/include/clang/StaticAnalyzer/Core/AnalyzerOptions.def (+5)
- (modified) clang/include/clang/StaticAnalyzer/Core/AnalyzerOptions.h (+3-5)
- (modified) clang/lib/StaticAnalyzer/Core/CMakeLists.txt (+1)
- (modified) clang/lib/StaticAnalyzer/Core/PlistDiagnostics.cpp (+60-11)
``````````diff
diff --git a/clang/include/clang/Analysis/PathDiagnostic.h b/clang/include/clang/Analysis/PathDiagnostic.h
index 5907df022e449..665edcf8756ad 100644
--- a/clang/include/clang/Analysis/PathDiagnostic.h
+++ b/clang/include/clang/Analysis/PathDiagnostic.h
@@ -68,6 +68,11 @@ struct PathDiagnosticConsumerOptions {
/// without re-compiling the program under analysis.
bool ShouldDisplayMacroExpansions = false;
+ /// Whether to include clang-formatted macros during macro expansions
+ /// or to keep it as it was stored, the default setting is to kee it as
+ /// is.
+ bool ShouldFormatMacrosPlist = false;
+
/// Whether to include LLVM statistics of the process in the diagnostic.
/// Useful for profiling the tool on large real-world codebases.
bool ShouldSerializeStats = false;
diff --git a/clang/include/clang/StaticAnalyzer/Core/AnalyzerOptions.def b/clang/include/clang/StaticAnalyzer/Core/AnalyzerOptions.def
index 90b80e5201aa8..3f19e3020ba42 100644
--- a/clang/include/clang/StaticAnalyzer/Core/AnalyzerOptions.def
+++ b/clang/include/clang/StaticAnalyzer/Core/AnalyzerOptions.def
@@ -351,6 +351,11 @@ ANALYZER_OPTION(bool, ShouldDisplayMacroExpansions, "expand-macros",
"expanded and included in the plist output.",
false)
+ANALYZER_OPTION(bool, ShouldFormatMacrosPlist, "format-macros-plist",
+ "Whether the macros being displayed in the plist "
+ "files are clang-formatted .",
+ false)
+
ANALYZER_OPTION(bool, DisplayCTUProgress, "display-ctu-progress",
"Whether to emit verbose output about "
"the analyzer's progress related to ctu.",
diff --git a/clang/include/clang/StaticAnalyzer/Core/AnalyzerOptions.h b/clang/include/clang/StaticAnalyzer/Core/AnalyzerOptions.h
index 7d0c2d8658f35..d8f32d659a6a1 100644
--- a/clang/include/clang/StaticAnalyzer/Core/AnalyzerOptions.h
+++ b/clang/include/clang/StaticAnalyzer/Core/AnalyzerOptions.h
@@ -403,16 +403,14 @@ class AnalyzerOptions {
bool mayInlineCXXMemberFunction(CXXInlineableMemberKind K) const;
ento::PathDiagnosticConsumerOptions getDiagOpts() const {
- return {FullCompilerInvocation,
- ShouldDisplayMacroExpansions,
- ShouldSerializeStats,
+ return {FullCompilerInvocation, ShouldDisplayMacroExpansions,
+ ShouldFormatMacrosPlist, ShouldSerializeStats,
// The stable report filename option is deprecated because
// file names are now always stable. Now the old option acts as
// an alias to the new verbose filename option because this
// closely mimics the behavior under the old option.
ShouldWriteStableReportFilename || ShouldWriteVerboseReportFilename,
- static_cast<bool>(AnalyzerWerror),
- ShouldApplyFixIts,
+ static_cast<bool>(AnalyzerWerror), ShouldApplyFixIts,
ShouldDisplayCheckerNameForText};
}
};
diff --git a/clang/lib/StaticAnalyzer/Core/CMakeLists.txt b/clang/lib/StaticAnalyzer/Core/CMakeLists.txt
index d0a9b202f9c52..6d51fcd0e7cc8 100644
--- a/clang/lib/StaticAnalyzer/Core/CMakeLists.txt
+++ b/clang/lib/StaticAnalyzer/Core/CMakeLists.txt
@@ -60,6 +60,7 @@ add_clang_library(clangStaticAnalyzerCore
clangAnalysis
clangBasic
clangCrossTU
+ clangFormat
clangFrontend
clangLex
clangRewrite
diff --git a/clang/lib/StaticAnalyzer/Core/PlistDiagnostics.cpp b/clang/lib/StaticAnalyzer/Core/PlistDiagnostics.cpp
index 771d09e19f178..d38e6491c1ce3 100644
--- a/clang/lib/StaticAnalyzer/Core/PlistDiagnostics.cpp
+++ b/clang/lib/StaticAnalyzer/Core/PlistDiagnostics.cpp
@@ -17,6 +17,7 @@
#include "clang/Basic/SourceManager.h"
#include "clang/Basic/Version.h"
#include "clang/CrossTU/CrossTranslationUnit.h"
+#include "clang/Format/Format.h"
#include "clang/Frontend/ASTUnit.h"
#include "clang/Lex/Preprocessor.h"
#include "clang/Lex/TokenConcatenation.h"
@@ -100,7 +101,8 @@ class PlistPrinter {
/// is found through a call piece, etc), it's subpieces are reported, and the
/// piece itself is collected. Call this function after the entire bugpath
/// was reported.
- void ReportMacroExpansions(raw_ostream &o, unsigned indent);
+ void ReportMacroExpansions(raw_ostream &o, unsigned indent,
+ bool ShouldFormatMacrosPlist);
private:
void ReportPiece(raw_ostream &o, const PathDiagnosticPiece &P,
@@ -163,9 +165,15 @@ static void printCoverage(const PathDiagnostic *D,
FIDMap &FM,
llvm::raw_fd_ostream &o);
-static std::optional<StringRef> getExpandedMacro(
- SourceLocation MacroLoc, const cross_tu::CrossTranslationUnitContext &CTU,
- const MacroExpansionContext &MacroExpansions, const SourceManager &SM);
+static std::optional<StringRef>
+getExpandedMacro(SourceLocation MacroLoc,
+ const cross_tu::CrossTranslationUnitContext &CTU,
+ const MacroExpansionContext &MacroExpansions,
+ const SourceManager &SM, bool ShouldFormatMacrosPlist);
+
+static std::optional<StringRef>
+getFormattedMacro(std::optional<StringRef> ExpandedText,
+ bool ShouldFormatMacrosPlist);
//===----------------------------------------------------------------------===//
// Methods of PlistPrinter.
@@ -372,7 +380,8 @@ void PlistPrinter::ReportMacroSubPieces(raw_ostream &o,
"Fixits on constrol flow pieces are not implemented yet!");
}
-void PlistPrinter::ReportMacroExpansions(raw_ostream &o, unsigned indent) {
+void PlistPrinter::ReportMacroExpansions(raw_ostream &o, unsigned indent,
+ bool ShouldFormatMacrosPlist) {
for (const PathDiagnosticMacroPiece *P : MacroPieces) {
const SourceManager &SM = PP.getSourceManager();
@@ -382,8 +391,8 @@ void PlistPrinter::ReportMacroExpansions(raw_ostream &o, unsigned indent) {
const std::optional<StringRef> MacroName =
MacroExpansions.getOriginalText(MacroExpansionLoc);
- const std::optional<StringRef> ExpansionText =
- getExpandedMacro(MacroExpansionLoc, CTU, MacroExpansions, SM);
+ const std::optional<StringRef> ExpansionText = getExpandedMacro(
+ MacroExpansionLoc, CTU, MacroExpansions, SM, ShouldFormatMacrosPlist);
if (!MacroName || !ExpansionText)
continue;
@@ -602,7 +611,8 @@ void PlistDiagnostics::printBugPath(llvm::raw_ostream &o, const FIDMap &FM,
o << " <key>macro_expansions</key>\n"
" <array>\n";
- Printer.ReportMacroExpansions(o, /* indent */ 4);
+ Printer.ReportMacroExpansions(o, /* indent */ 4,
+ DiagOpts.ShouldFormatMacrosPlist);
o << " </array>\n";
}
@@ -824,10 +834,49 @@ static std::optional<StringRef>
getExpandedMacro(SourceLocation MacroExpansionLoc,
const cross_tu::CrossTranslationUnitContext &CTU,
const MacroExpansionContext &MacroExpansions,
- const SourceManager &SM) {
+ const SourceManager &SM, bool ShouldFormatMacrosPlist) {
+ std::optional<StringRef> ExpandedText;
if (auto CTUMacroExpCtx =
CTU.getMacroExpansionContextForSourceLocation(MacroExpansionLoc)) {
- return CTUMacroExpCtx->getExpandedText(MacroExpansionLoc);
+ ExpandedText = CTUMacroExpCtx->getExpandedText(MacroExpansionLoc);
+ } else {
+ ExpandedText = MacroExpansions.getExpandedText(MacroExpansionLoc);
}
- return MacroExpansions.getExpandedText(MacroExpansionLoc);
+
+ std::optional<StringRef> FormattedMacroText =
+ getFormattedMacro(ExpandedText, ShouldFormatMacrosPlist);
+ return FormattedMacroText;
}
+
+static std::optional<StringRef>
+getFormattedMacro(std::optional<StringRef> ExpandedText,
+ bool ShouldFormatMacrosPlist) {
+ if (!ExpandedText) {
+ return std::nullopt;
+ }
+
+ if (!ShouldFormatMacrosPlist) {
+ return *ExpandedText;
+ }
+
+ clang::format::FormatStyle Style = clang::format::getLLVMStyle();
+
+ std::string MacroCodeBlock = ExpandedText->str();
+
+ std::vector<clang::tooling::Range> Ranges;
+ Ranges.emplace_back(0, MacroCodeBlock.length());
+
+ auto Replacements = clang::format::reformat(Style, MacroCodeBlock, Ranges,
+ "<macro-expansion>");
+
+ auto Result =
+ clang::tooling::applyAllReplacements(MacroCodeBlock, Replacements);
+ if (!Result) {
+ return *ExpandedText;
+ }
+
+ static std::vector<std::string> FormattedResults;
+ FormattedResults.emplace_back(*Result);
+
+ return StringRef(FormattedResults.back());
+}
\ No newline at end of file
``````````
</details>
https://github.com/llvm/llvm-project/pull/156046
More information about the cfe-commits
mailing list