clang  3.7.0
FormatString.h
Go to the documentation of this file.
1 //= FormatString.h - Analysis of printf/fprintf format strings --*- C++ -*-===//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This file defines APIs for analyzing the format strings of printf, fscanf,
11 // and friends.
12 //
13 // The structure of format strings for fprintf are described in C99 7.19.6.1.
14 //
15 // The structure of format strings for fscanf are described in C99 7.19.6.2.
16 //
17 //===----------------------------------------------------------------------===//
18 
19 #ifndef LLVM_CLANG_ANALYSIS_ANALYSES_FORMATSTRING_H
20 #define LLVM_CLANG_ANALYSIS_ANALYSES_FORMATSTRING_H
21 
23 
24 namespace clang {
25 
26 class TargetInfo;
27 
28 //===----------------------------------------------------------------------===//
29 /// Common components of both fprintf and fscanf format strings.
30 namespace analyze_format_string {
31 
32 /// Class representing optional flags with location and representation
33 /// information.
34 class OptionalFlag {
35 public:
36  OptionalFlag(const char *Representation)
37  : representation(Representation), flag(false) {}
38  bool isSet() { return flag; }
39  void set() { flag = true; }
40  void clear() { flag = false; }
41  void setPosition(const char *position) {
42  assert(position);
43  flag = true;
44  this->position = position;
45  }
46  const char *getPosition() const {
47  assert(position);
48  return position;
49  }
50  const char *toString() const { return representation; }
51 
52  // Overloaded operators for bool like qualities
53  explicit operator bool() const { return flag; }
54  OptionalFlag& operator=(const bool &rhs) {
55  flag = rhs;
56  return *this; // Return a reference to myself.
57  }
58 private:
59  const char *representation;
60  const char *position;
61  bool flag;
62 };
63 
64 /// Represents the length modifier in a format string in scanf/printf.
66 public:
67  enum Kind {
69  AsChar, // 'hh'
70  AsShort, // 'h'
71  AsLong, // 'l'
72  AsLongLong, // 'll'
73  AsQuad, // 'q' (BSD, deprecated, for 64-bit integer types)
74  AsIntMax, // 'j'
75  AsSizeT, // 'z'
76  AsPtrDiff, // 't'
77  AsInt32, // 'I32' (MSVCRT, like __int32)
78  AsInt3264, // 'I' (MSVCRT, like __int3264 from MIDL)
79  AsInt64, // 'I64' (MSVCRT, like __int64)
80  AsLongDouble, // 'L'
81  AsAllocate, // for '%as', GNU extension to C90 scanf
82  AsMAllocate, // for '%ms', GNU extension to scanf
83  AsWide, // 'w' (MSVCRT, like l but only for c, C, s, S, or Z
84  AsWideChar = AsLong // for '%ls', only makes sense for printf
85  };
86 
88  : Position(nullptr), kind(None) {}
89  LengthModifier(const char *pos, Kind k)
90  : Position(pos), kind(k) {}
91 
92  const char *getStart() const {
93  return Position;
94  }
95 
96  unsigned getLength() const {
97  switch (kind) {
98  default:
99  return 1;
100  case AsLongLong:
101  case AsChar:
102  return 2;
103  case AsInt32:
104  case AsInt64:
105  return 3;
106  case None:
107  return 0;
108  }
109  }
110 
111  Kind getKind() const { return kind; }
112  void setKind(Kind k) { kind = k; }
113 
114  const char *toString() const;
115 
116 private:
117  const char *Position;
118  Kind kind;
119 };
120 
122 public:
123  enum Kind {
125  // C99 conversion specifiers.
128  DArg, // Apple extension
131 
133  OArg, // Apple extension
135  UArg, // Apple extension
139 
149 
156 
157  // ** Printf-specific **
158 
159  ZArg, // MS extension
160 
161  // Objective-C specific specifiers.
162  ObjCObjArg, // '@'
164 
165  // FreeBSD kernel specific specifiers.
170 
171  // GlibC specific specifiers.
172  PrintErrno, // 'm'
173 
175 
176  // ** Scanf-specific **
177  ScanListArg, // '['
179  };
180 
181  ConversionSpecifier(bool isPrintf = true)
182  : IsPrintf(isPrintf), Position(nullptr), EndScanList(nullptr),
184 
185  ConversionSpecifier(bool isPrintf, const char *pos, Kind k)
186  : IsPrintf(isPrintf), Position(pos), EndScanList(nullptr), kind(k) {}
187 
188  const char *getStart() const {
189  return Position;
190  }
191 
192  StringRef getCharacters() const {
193  return StringRef(getStart(), getLength());
194  }
195 
196  bool consumesDataArgument() const {
197  switch (kind) {
198  case PrintErrno:
199  assert(IsPrintf);
200  return false;
201  case PercentArg:
202  return false;
203  default:
204  return true;
205  }
206  }
207 
208  Kind getKind() const { return kind; }
209  void setKind(Kind k) { kind = k; }
210  unsigned getLength() const {
211  return EndScanList ? EndScanList - Position : 1;
212  }
213 
214  bool isIntArg() const { return (kind >= IntArgBeg && kind <= IntArgEnd) ||
215  kind == FreeBSDrArg || kind == FreeBSDyArg; }
216  bool isUIntArg() const { return kind >= UIntArgBeg && kind <= UIntArgEnd; }
217  bool isAnyIntArg() const { return kind >= IntArgBeg && kind <= UIntArgEnd; }
218  const char *toString() const;
219 
220  bool isPrintfKind() const { return IsPrintf; }
221 
223 
224 protected:
225  bool IsPrintf;
226  const char *Position;
227  const char *EndScanList;
229 };
230 
231 class ArgType {
232 public:
235 
237 
238 private:
239  const Kind K;
240  QualType T;
241  const char *Name;
242  bool Ptr;
243 public:
244  ArgType(Kind k = UnknownTy, const char *n = nullptr)
245  : K(k), Name(n), Ptr(false) {}
246  ArgType(QualType t, const char *n = nullptr)
247  : K(SpecificTy), T(t), Name(n), Ptr(false) {}
248  ArgType(CanQualType t) : K(SpecificTy), T(t), Name(nullptr), Ptr(false) {}
249 
250  static ArgType Invalid() { return ArgType(InvalidTy); }
251  bool isValid() const { return K != InvalidTy; }
252 
253  /// Create an ArgType which corresponds to the type pointer to A.
254  static ArgType PtrTo(const ArgType& A) {
255  assert(A.K >= InvalidTy && "ArgType cannot be pointer to invalid/unknown");
256  ArgType Res = A;
257  Res.Ptr = true;
258  return Res;
259  }
260 
261  MatchKind matchesType(ASTContext &C, QualType argTy) const;
262 
264 
265  std::string getRepresentativeTypeName(ASTContext &C) const;
266 };
267 
269 public:
271 
273  unsigned amount,
274  const char *amountStart,
275  unsigned amountLength,
276  bool usesPositionalArg)
277  : start(amountStart), length(amountLength), hs(howSpecified), amt(amount),
278  UsesPositionalArg(usesPositionalArg), UsesDotPrefix(0) {}
279 
280  OptionalAmount(bool valid = true)
281  : start(nullptr),length(0), hs(valid ? NotSpecified : Invalid), amt(0),
282  UsesPositionalArg(0), UsesDotPrefix(0) {}
283 
284  bool isInvalid() const {
285  return hs == Invalid;
286  }
287 
288  HowSpecified getHowSpecified() const { return hs; }
289  void setHowSpecified(HowSpecified h) { hs = h; }
290 
291  bool hasDataArgument() const { return hs == Arg; }
292 
293  unsigned getArgIndex() const {
294  assert(hasDataArgument());
295  return amt;
296  }
297 
298  unsigned getConstantAmount() const {
299  assert(hs == Constant);
300  return amt;
301  }
302 
303  const char *getStart() const {
304  // We include the . character if it is given.
305  return start - UsesDotPrefix;
306  }
307 
308  unsigned getConstantLength() const {
309  assert(hs == Constant);
310  return length + UsesDotPrefix;
311  }
312 
313  ArgType getArgType(ASTContext &Ctx) const;
314 
315  void toString(raw_ostream &os) const;
316 
317  bool usesPositionalArg() const { return (bool) UsesPositionalArg; }
318  unsigned getPositionalArgIndex() const {
319  assert(hasDataArgument());
320  return amt + 1;
321  }
322 
323  bool usesDotPrefix() const { return UsesDotPrefix; }
324  void setUsesDotPrefix() { UsesDotPrefix = true; }
325 
326 private:
327  const char *start;
328  unsigned length;
329  HowSpecified hs;
330  unsigned amt;
331  bool UsesPositionalArg : 1;
332  bool UsesDotPrefix;
333 };
334 
335 
337 protected:
341  /// Positional arguments, an IEEE extension:
342  /// IEEE Std 1003.1, 2004 Edition
343  /// http://www.opengroup.org/onlinepubs/009695399/functions/printf.html
345  unsigned argIndex;
346 public:
347  FormatSpecifier(bool isPrintf)
348  : CS(isPrintf), UsesPositionalArg(false), argIndex(0) {}
349 
351  LM = lm;
352  }
353 
355 
356  void setArgIndex(unsigned i) {
357  argIndex = i;
358  }
359 
360  unsigned getArgIndex() const {
361  return argIndex;
362  }
363 
364  unsigned getPositionalArgIndex() const {
365  return argIndex + 1;
366  }
367 
369  return LM;
370  }
371 
372  const OptionalAmount &getFieldWidth() const {
373  return FieldWidth;
374  }
375 
376  void setFieldWidth(const OptionalAmount &Amt) {
377  FieldWidth = Amt;
378  }
379 
380  bool usesPositionalArg() const { return UsesPositionalArg; }
381 
382  bool hasValidLengthModifier(const TargetInfo &Target) const;
383 
384  bool hasStandardLengthModifier() const;
385 
387 
388  bool hasStandardConversionSpecifier(const LangOptions &LangOpt) const;
389 
391 
392  /// For a TypedefType QT, if it is a named integer type such as size_t,
393  /// assign the appropriate value to LM and return true.
395 };
396 
397 } // end analyze_format_string namespace
398 
399 //===----------------------------------------------------------------------===//
400 /// Pieces specific to fprintf format strings.
401 
402 namespace analyze_printf {
403 
406 public:
409 
410  PrintfConversionSpecifier(const char *pos, Kind k)
411  : ConversionSpecifier(true, pos, k) {}
412 
413  bool isObjCArg() const { return kind >= ObjCBeg && kind <= ObjCEnd; }
414  bool isDoubleArg() const { return kind >= DoubleArgBeg &&
415  kind <= DoubleArgEnd; }
416  unsigned getLength() const {
417  // Conversion specifiers currently only are represented by
418  // single characters, but we be flexible.
419  return 1;
420  }
421 
423  return CS->isPrintfKind();
424  }
425 };
426 
431 
433  OptionalFlag HasThousandsGrouping; // ''', POSIX extension.
434  OptionalFlag IsLeftJustified; // '-'
435  OptionalFlag HasPlusPrefix; // '+'
436  OptionalFlag HasSpacePrefix; // ' '
437  OptionalFlag HasAlternativeForm; // '#'
438  OptionalFlag HasLeadingZeroes; // '0'
439  OptionalFlag HasObjCTechnicalTerm; // '[tt]'
440  OptionalAmount Precision;
441 public:
443  FormatSpecifier(/* isPrintf = */ true),
444  HasThousandsGrouping("'"), IsLeftJustified("-"), HasPlusPrefix("+"),
445  HasSpacePrefix(" "), HasAlternativeForm("#"), HasLeadingZeroes("0"),
446  HasObjCTechnicalTerm("tt") {}
447 
448  static PrintfSpecifier Parse(const char *beg, const char *end);
449 
450  // Methods for incrementally constructing the PrintfSpecifier.
452  CS = cs;
453  }
454  void setHasThousandsGrouping(const char *position) {
455  HasThousandsGrouping.setPosition(position);
456  }
457  void setIsLeftJustified(const char *position) {
458  IsLeftJustified.setPosition(position);
459  }
460  void setHasPlusPrefix(const char *position) {
461  HasPlusPrefix.setPosition(position);
462  }
463  void setHasSpacePrefix(const char *position) {
464  HasSpacePrefix.setPosition(position);
465  }
466  void setHasAlternativeForm(const char *position) {
467  HasAlternativeForm.setPosition(position);
468  }
469  void setHasLeadingZeros(const char *position) {
470  HasLeadingZeroes.setPosition(position);
471  }
472  void setHasObjCTechnicalTerm(const char *position) {
473  HasObjCTechnicalTerm.setPosition(position);
474  }
476 
477  // Methods for querying the format specifier.
478 
480  return cast<PrintfConversionSpecifier>(CS);
481  }
482 
483  void setPrecision(const OptionalAmount &Amt) {
484  Precision = Amt;
485  Precision.setUsesDotPrefix();
486  }
487 
488  const OptionalAmount &getPrecision() const {
489  return Precision;
490  }
491 
492  bool consumesDataArgument() const {
494  }
495 
496  /// \brief Returns the builtin type that a data argument
497  /// paired with this format specifier should have. This method
498  /// will return null if the format specifier does not have
499  /// a matching data argument or the matching argument matches
500  /// more than one type.
501  ArgType getArgType(ASTContext &Ctx, bool IsObjCLiteral) const;
502 
503  const OptionalFlag &hasThousandsGrouping() const {
504  return HasThousandsGrouping;
505  }
506  const OptionalFlag &isLeftJustified() const { return IsLeftJustified; }
507  const OptionalFlag &hasPlusPrefix() const { return HasPlusPrefix; }
508  const OptionalFlag &hasAlternativeForm() const { return HasAlternativeForm; }
509  const OptionalFlag &hasLeadingZeros() const { return HasLeadingZeroes; }
510  const OptionalFlag &hasSpacePrefix() const { return HasSpacePrefix; }
511  const OptionalFlag &hasObjCTechnicalTerm() const { return HasObjCTechnicalTerm; }
512  bool usesPositionalArg() const { return UsesPositionalArg; }
513 
514  /// Changes the specifier and length according to a QualType, retaining any
515  /// flags or options. Returns true on success, or false when a conversion
516  /// was not successful.
517  bool fixType(QualType QT, const LangOptions &LangOpt, ASTContext &Ctx,
518  bool IsObjCLiteral);
519 
520  void toString(raw_ostream &os) const;
521 
522  // Validation methods - to check if any element results in undefined behavior
523  bool hasValidPlusPrefix() const;
524  bool hasValidAlternativeForm() const;
525  bool hasValidLeadingZeros() const;
526  bool hasValidSpacePrefix() const;
527  bool hasValidLeftJustified() const;
528  bool hasValidThousandsGroupingPrefix() const;
529 
530  bool hasValidPrecision() const;
531  bool hasValidFieldWidth() const;
532 };
533 } // end analyze_printf namespace
534 
535 //===----------------------------------------------------------------------===//
536 /// Pieces specific to fscanf format strings.
537 
538 namespace analyze_scanf {
539 
542 public:
545 
546  ScanfConversionSpecifier(const char *pos, Kind k)
547  : ConversionSpecifier(false, pos, k) {}
548 
549  void setEndScanList(const char *pos) { EndScanList = pos; }
550 
552  return !CS->isPrintfKind();
553  }
554 };
555 
560 
562  OptionalFlag SuppressAssignment; // '*'
563 public:
565  FormatSpecifier(/* isPrintf = */ false),
566  SuppressAssignment("*") {}
567 
568  void setSuppressAssignment(const char *position) {
569  SuppressAssignment.setPosition(position);
570  }
571 
572  const OptionalFlag &getSuppressAssignment() const {
573  return SuppressAssignment;
574  }
575 
577  CS = cs;
578  }
579 
581  return cast<ScanfConversionSpecifier>(CS);
582  }
583 
584  bool consumesDataArgument() const {
585  return CS.consumesDataArgument() && !SuppressAssignment;
586  }
587 
588  ArgType getArgType(ASTContext &Ctx) const;
589 
590  bool fixType(QualType QT, QualType RawQT, const LangOptions &LangOpt,
591  ASTContext &Ctx);
592 
593  void toString(raw_ostream &os) const;
594 
595  static ScanfSpecifier Parse(const char *beg, const char *end);
596 };
597 
598 } // end analyze_scanf namespace
599 
600 //===----------------------------------------------------------------------===//
601 // Parsing and processing of format strings (both fprintf and fscanf).
602 
603 namespace analyze_format_string {
604 
606 
608 public:
610  virtual ~FormatStringHandler();
611 
612  virtual void HandleNullChar(const char *nullCharacter) {}
613 
614  virtual void HandlePosition(const char *startPos, unsigned posLen) {}
615 
616  virtual void HandleInvalidPosition(const char *startPos, unsigned posLen,
617  PositionContext p) {}
618 
619  virtual void HandleZeroPosition(const char *startPos, unsigned posLen) {}
620 
621  virtual void HandleIncompleteSpecifier(const char *startSpecifier,
622  unsigned specifierLen) {}
623 
624  virtual void HandleEmptyObjCModifierFlag(const char *startFlags,
625  unsigned flagsLen) {}
626 
627  virtual void HandleInvalidObjCModifierFlag(const char *startFlag,
628  unsigned flagLen) {}
629 
630  virtual void HandleObjCFlagsWithNonObjCConversion(const char *flagsStart,
631  const char *flagsEnd,
632  const char *conversionPosition) {}
633  // Printf-specific handlers.
634 
637  const char *startSpecifier,
638  unsigned specifierLen) {
639  return true;
640  }
641 
643  const char *startSpecifier,
644  unsigned specifierLen) {
645  return true;
646  }
647 
648  // Scanf-specific handlers.
649 
652  const char *startSpecifier,
653  unsigned specifierLen) {
654  return true;
655  }
656 
658  const char *startSpecifier,
659  unsigned specifierLen) {
660  return true;
661  }
662 
663  virtual void HandleIncompleteScanList(const char *start, const char *end) {}
664 };
665 
666 bool ParsePrintfString(FormatStringHandler &H,
667  const char *beg, const char *end, const LangOptions &LO,
668  const TargetInfo &Target, bool isFreeBSDKPrintf);
669 
670 bool ParseFormatStringHasSArg(const char *beg, const char *end,
671  const LangOptions &LO, const TargetInfo &Target);
672 
673 bool ParseScanfString(FormatStringHandler &H,
674  const char *beg, const char *end, const LangOptions &LO,
675  const TargetInfo &Target);
676 
677 } // end analyze_format_string namespace
678 } // end clang namespace
679 #endif
const OptionalFlag & hasSpacePrefix() const
Definition: FormatString.h:510
virtual void HandlePosition(const char *startPos, unsigned posLen)
Definition: FormatString.h:614
virtual bool HandleScanfSpecifier(const analyze_scanf::ScanfSpecifier &FS, const char *startSpecifier, unsigned specifierLen)
Definition: FormatString.h:657
MatchKind matchesType(ASTContext &C, QualType argTy) const
const OptionalFlag & getSuppressAssignment() const
Definition: FormatString.h:572
Optional< LengthModifier > getCorrectedLengthModifier() const
const ScanfConversionSpecifier & getConversionSpecifier() const
Definition: FormatString.h:580
virtual void HandleInvalidObjCModifierFlag(const char *startFlag, unsigned flagLen)
Definition: FormatString.h:627
bool hasStandardConversionSpecifier(const LangOptions &LangOpt) const
ArgType(QualType t, const char *n=nullptr)
Definition: FormatString.h:246
const LengthModifier & getLengthModifier() const
Definition: FormatString.h:368
virtual void HandleZeroPosition(const char *startPos, unsigned posLen)
Definition: FormatString.h:619
OptionalFlag(const char *Representation)
Definition: FormatString.h:36
void setPosition(const char *position)
Definition: FormatString.h:41
const OptionalFlag & hasLeadingZeros() const
Definition: FormatString.h:509
std::string getRepresentativeTypeName(ASTContext &C) const
void setHasLeadingZeros(const char *position)
Definition: FormatString.h:469
ArgType getArgType(ASTContext &Ctx, bool IsObjCLiteral) const
Returns the builtin type that a data argument paired with this format specifier should have...
static ScanfSpecifier Parse(const char *beg, const char *end)
PrintfConversionSpecifier(const char *pos, Kind k)
Definition: FormatString.h:410
static bool classof(const analyze_format_string::ConversionSpecifier *CS)
Definition: FormatString.h:551
virtual void HandleEmptyObjCModifierFlag(const char *startFlags, unsigned flagsLen)
Definition: FormatString.h:624
void setPrecision(const OptionalAmount &Amt)
Definition: FormatString.h:483
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
Definition: ASTContext.h:89
bool ParseScanfString(FormatStringHandler &H, const char *beg, const char *end, const LangOptions &LO, const TargetInfo &Target)
void setHasSpacePrefix(const char *position)
Definition: FormatString.h:463
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
Definition: LangOptions.h:48
void setConversionSpecifier(const PrintfConversionSpecifier &cs)
Definition: FormatString.h:451
void setFieldWidth(const OptionalAmount &Amt)
Definition: FormatString.h:376
virtual bool HandleInvalidPrintfConversionSpecifier(const analyze_printf::PrintfSpecifier &FS, const char *startSpecifier, unsigned specifierLen)
Definition: FormatString.h:635
Optional< ConversionSpecifier > getStandardSpecifier() const
Represents the length modifier in a format string in scanf/printf.
Definition: FormatString.h:65
void setIsLeftJustified(const char *position)
Definition: FormatString.h:457
bool fixType(QualType QT, QualType RawQT, const LangOptions &LangOpt, ASTContext &Ctx)
static ArgType PtrTo(const ArgType &A)
Create an ArgType which corresponds to the type pointer to A.
Definition: FormatString.h:254
ScanfConversionSpecifier(const char *pos, Kind k)
Definition: FormatString.h:546
Exposes information about the current target.
const OptionalFlag & hasObjCTechnicalTerm() const
Definition: FormatString.h:511
#define bool
Definition: stdbool.h:31
virtual void HandleNullChar(const char *nullCharacter)
Definition: FormatString.h:612
bool fixType(QualType QT, const LangOptions &LangOpt, ASTContext &Ctx, bool IsObjCLiteral)
const PrintfConversionSpecifier & getConversionSpecifier() const
Definition: FormatString.h:479
bool ParseFormatStringHasSArg(const char *beg, const char *end, const LangOptions &LO, const TargetInfo &Target)
virtual void HandleObjCFlagsWithNonObjCConversion(const char *flagsStart, const char *flagsEnd, const char *conversionPosition)
Definition: FormatString.h:630
#define false
Definition: stdbool.h:33
Kind
virtual void HandleInvalidPosition(const char *startPos, unsigned posLen, PositionContext p)
Definition: FormatString.h:616
static bool namedTypeToLengthModifier(QualType QT, LengthModifier &LM)
const OptionalFlag & hasPlusPrefix() const
Definition: FormatString.h:507
void setHasThousandsGrouping(const char *position)
Definition: FormatString.h:454
void setConversionSpecifier(const ScanfConversionSpecifier &cs)
Definition: FormatString.h:576
const OptionalAmount & getFieldWidth() const
Definition: FormatString.h:372
virtual bool HandlePrintfSpecifier(const analyze_printf::PrintfSpecifier &FS, const char *startSpecifier, unsigned specifierLen)
Definition: FormatString.h:642
void setSuppressAssignment(const char *position)
Definition: FormatString.h:568
static __inline__ uint32_t volatile uint32_t * p
Definition: arm_acle.h:75
const OptionalFlag & hasThousandsGrouping() const
Definition: FormatString.h:503
OptionalFlag & operator=(const bool &rhs)
Definition: FormatString.h:54
ArgType(Kind k=UnknownTy, const char *n=nullptr)
Definition: FormatString.h:244
ArgType getArgType(ASTContext &Ctx) const
OptionalAmount(HowSpecified howSpecified, unsigned amount, const char *amountStart, unsigned amountLength, bool usesPositionalArg)
Definition: FormatString.h:272
void setHasObjCTechnicalTerm(const char *position)
Definition: FormatString.h:472
QualType getRepresentativeType(ASTContext &C) const
static PrintfSpecifier Parse(const char *beg, const char *end)
const OptionalAmount & getPrecision() const
Definition: FormatString.h:488
const OptionalFlag & hasAlternativeForm() const
Definition: FormatString.h:508
void setHasPlusPrefix(const char *position)
Definition: FormatString.h:460
void toString(raw_ostream &os) const
const OptionalFlag & isLeftJustified() const
Definition: FormatString.h:506
virtual void HandleIncompleteSpecifier(const char *startSpecifier, unsigned specifierLen)
Definition: FormatString.h:621
static bool classof(const analyze_format_string::ConversionSpecifier *CS)
Definition: FormatString.h:422
ConversionSpecifier(bool isPrintf, const char *pos, Kind k)
Definition: FormatString.h:185
ArgType getArgType(ASTContext &Ctx) const
bool ParsePrintfString(FormatStringHandler &H, const char *beg, const char *end, const LangOptions &LO, const TargetInfo &Target, bool isFreeBSDKPrintf)
void setHasAlternativeForm(const char *position)
Definition: FormatString.h:466
#define true
Definition: stdbool.h:32
bool hasValidLengthModifier(const TargetInfo &Target) const
virtual void HandleIncompleteScanList(const char *start, const char *end)
Definition: FormatString.h:663
virtual bool HandleInvalidScanfConversionSpecifier(const analyze_scanf::ScanfSpecifier &FS, const char *startSpecifier, unsigned specifierLen)
Definition: FormatString.h:650