15#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_UTILS_FORMATSTRINGCONVERTER_H
16#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_UTILS_FORMATSTRINGCONVERTER_H
18#include "clang/AST/ASTContext.h"
19#include "clang/AST/FormatString.h"
20#include "clang/ASTMatchers/ASTMatchers.h"
43 const LangOptions &LO, SourceManager &SM,
46 bool canApply()
const {
return ConversionNotPossibleReason.empty(); }
48 return ConversionNotPossibleReason;
50 void applyFixes(DiagnosticBuilder &Diag, SourceManager &SM);
55 const Configuration Config;
56 const bool CastMismatchedIntegerTypes;
57 const Expr *
const *Args;
58 const unsigned NumArgs;
60 const LangOptions &LangOpts;
61 std::string ConversionNotPossibleReason;
62 bool FormatStringNeededRewriting =
false;
63 bool UsePrintNewlineFunction =
false;
64 size_t PrintfFormatStringPos = 0U;
65 StringRef PrintfFormatString;
68 std::optional<clang::ast_matchers::StatementMatcher>
69 StringCStrCallExprMatcher;
71 const StringLiteral *FormatExpr;
72 std::string StandardFormatString;
80 explicit ArgumentFix(
unsigned ArgIndex, std::string Fix)
81 : ArgIndex(ArgIndex), Fix(std::move(Fix)) {}
84 std::vector<ArgumentFix> ArgFixes;
85 std::vector<clang::ast_matchers::BoundNodes> ArgCStrRemovals;
90 std::vector<std::tuple<unsigned, unsigned>> ArgRotates;
94 void emitAlternativeForm(
const PrintfSpecifier &FS, std::string &FormatSpec);
95 void emitFieldWidth(
const PrintfSpecifier &FS, std::string &FormatSpec);
97 void emitStringArgument(
unsigned ArgIndex,
const Expr *Arg);
98 bool emitIntegerArgument(ConversionSpecifier::Kind ArgKind,
const Expr *Arg,
99 unsigned ArgIndex, std::string &FormatSpec);
102 std::string &FormatSpec);
104 std::string &StandardFormatString);
109 const char *StartSpecifier,
unsigned SpecifierLen,
110 const TargetInfo &Target)
override;
112 void appendFormatText(StringRef
Text);
113 void finalizeFormatText();
114 static std::optional<StringRef>
115 formatStringContainsUnreplaceableMacro(
const CallExpr *CallExpr,
116 const StringLiteral *FormatExpr,
117 SourceManager &SM, Preprocessor &PP);
118 bool conversionNotPossible(std::string Reason) {
119 ConversionNotPossibleReason = std::move(Reason);