Clang Project

clang_source_code/include/clang/AST/FormatString.h
1//= FormatString.h - Analysis of printf/fprintf format strings --*- C++ -*-===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// This file defines APIs for analyzing the format strings of printf, fscanf,
10// and friends.
11//
12// The structure of format strings for fprintf are described in C99 7.19.6.1.
13//
14// The structure of format strings for fscanf are described in C99 7.19.6.2.
15//
16//===----------------------------------------------------------------------===//
17
18#ifndef LLVM_CLANG_ANALYSIS_ANALYSES_FORMATSTRING_H
19#define LLVM_CLANG_ANALYSIS_ANALYSES_FORMATSTRING_H
20
21#include "clang/AST/CanonicalType.h"
22
23namespace clang {
24
25class TargetInfo;
26
27//===----------------------------------------------------------------------===//
28/// Common components of both fprintf and fscanf format strings.
29namespace analyze_format_string {
30
31/// Class representing optional flags with location and representation
32/// information.
33class OptionalFlag {
34public:
35  OptionalFlag(const char *Representation)
36      : representation(Representation), flag(false) {}
37  bool isSet() const { return flag; }
38  void set() { flag = true; }
39  void clear() { flag = false; }
40  void setPosition(const char *position) {
41    assert(position);
42    flag = true;
43    this->position = position;
44  }
45  const char *getPosition() const {
46    assert(position);
47    return position;
48  }
49  const char *toString() const { return representation; }
50
51  // Overloaded operators for bool like qualities
52  explicit operator bool() const { return flag; }
53  OptionalFlagoperator=(const bool &rhs) {
54    flag = rhs;
55    return *this;  // Return a reference to myself.
56  }
57private:
58  const char *representation;
59  const char *position;
60  bool flag;
61};
62
63/// Represents the length modifier in a format string in scanf/printf.
64class LengthModifier {
65public:
66  enum Kind {
67    None,
68    AsChar,       // 'hh'
69    AsShort,      // 'h'
70    AsShortLong,  // 'hl' (OpenCL float/int vector element)
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
87  LengthModifier()
88    : Position(nullptr), kind(None) {}
89  LengthModifier(const char *posKind 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
116private:
117  const char *Position;
118  Kind kind;
119};
120
121class ConversionSpecifier {
122public:
123  enum Kind {
124    InvalidSpecifier = 0,
125    // C99 conversion specifiers.
126    cArg,
127    dArg,
128    DArg// Apple extension
129    iArg,
130    IntArgBeg = dArg,
131    IntArgEnd = iArg,
132
133    oArg,
134    OArg// Apple extension
135    uArg,
136    UArg// Apple extension
137    xArg,
138    XArg,
139    UIntArgBeg = oArg,
140    UIntArgEnd = XArg,
141
142    fArg,
143    FArg,
144    eArg,
145    EArg,
146    gArg,
147    GArg,
148    aArg,
149    AArg,
150    DoubleArgBeg = fArg,
151    DoubleArgEnd = AArg,
152
153    sArg,
154    pArg,
155    nArg,
156    PercentArg,
157    CArg,
158    SArg,
159
160    // Apple extension: P specifies to os_log that the data being pointed to is
161    // to be copied by os_log. The precision indicates the number of bytes to
162    // copy.
163    PArg,
164
165    // ** Printf-specific **
166
167    ZArg// MS extension
168
169    // Objective-C specific specifiers.
170    ObjCObjArg// '@'
171    ObjCBeg = ObjCObjArg,
172    ObjCEnd = ObjCObjArg,
173
174    // FreeBSD kernel specific specifiers.
175    FreeBSDbArg,
176    FreeBSDDArg,
177    FreeBSDrArg,
178    FreeBSDyArg,
179
180    // GlibC specific specifiers.
181    PrintErrno// 'm'
182
183    PrintfConvBeg = ObjCObjArg,
184    PrintfConvEnd = PrintErrno,
185
186    // ** Scanf-specific **
187    ScanListArg// '['
188    ScanfConvBeg = ScanListArg,
189    ScanfConvEnd = ScanListArg
190  };
191
192  ConversionSpecifier(bool isPrintf = true)
193    : IsPrintf(isPrintf), Position(nullptr), EndScanList(nullptr),
194      kind(InvalidSpecifier) {}
195
196  ConversionSpecifier(bool isPrintfconst char *posKind k)
197    : IsPrintf(isPrintf), Position(pos), EndScanList(nullptr), kind(k) {}
198
199  const char *getStart() const {
200    return Position;
201  }
202
203  StringRef getCharacters() const {
204    return StringRef(getStart(), getLength());
205  }
206
207  bool consumesDataArgument() const {
208    switch (kind) {
209      case PrintErrno:
210        assert(IsPrintf);
211        return false;
212      case PercentArg:
213        return false;
214      case InvalidSpecifier:
215        return false;
216      default:
217        return true;
218    }
219  }
220
221  Kind getKind() const { return kind; }
222  void setKind(Kind k) { kind = k; }
223  unsigned getLength() const {
224    return EndScanList ? EndScanList - Position : 1;
225  }
226  void setEndScanList(const char *pos) { EndScanList = pos; }
227
228  bool isIntArg() const { return (kind >= IntArgBeg && kind <= IntArgEnd) ||
229    kind == FreeBSDrArg || kind == FreeBSDyArg; }
230  bool isUIntArg() const { return kind >= UIntArgBeg && kind <= UIntArgEnd; }
231  bool isAnyIntArg() const { return kind >= IntArgBeg && kind <= UIntArgEnd; }
232  bool isDoubleArg() const {
233    return kind >= DoubleArgBeg && kind <= DoubleArgEnd;
234  }
235
236  const char *toString() const;
237
238  bool isPrintfKind() const { return IsPrintf; }
239
240  Optional<ConversionSpecifiergetStandardSpecifier() const;
241
242protected:
243  bool IsPrintf;
244  const char *Position;
245  const char *EndScanList;
246  Kind kind;
247};
248
249class ArgType {
250public:
251  enum Kind { UnknownTyInvalidTySpecificTyObjCPointerTyCPointerTy,
252              AnyCharTyCStrTyWCStrTyWIntTy };
253
254  enum MatchKind { NoMatch = 0Match = 1NoMatchPedantic };
255
256private:
257  const Kind K;
258  QualType T;
259  const char *Name = nullptr;
260  bool Ptr = false;
261
262  /// The TypeKind identifies certain well-known types like size_t and
263  /// ptrdiff_t.
264  enum class TypeKind { DontCareSizeTPtrdiffT };
265  TypeKind TK = TypeKind::DontCare;
266
267public:
268  ArgType(Kind K = UnknownTyconst char *N = nullptr) : K(K), Name(N) {}
269  ArgType(QualType Tconst char *N = nullptr) : K(SpecificTy), T(T), Name(N) {}
270  ArgType(CanQualType T) : K(SpecificTy), T(T) {}
271
272  static ArgType Invalid() { return ArgType(InvalidTy); }
273  bool isValid() const { return K != InvalidTy; }
274
275  bool isSizeT() const { return TK == TypeKind::SizeT; }
276
277  bool isPtrdiffT() const { return TK == TypeKind::PtrdiffT; }
278
279  /// Create an ArgType which corresponds to the type pointer to A.
280  static ArgType PtrTo(const ArgTypeA) {
281     (0) . __assert_fail ("A.K >= InvalidTy && \"ArgType cannot be pointer to invalid/unknown\"", "/home/seafit/code_projects/clang_source/clang/include/clang/AST/FormatString.h", 281, __PRETTY_FUNCTION__))" file_link="../../../../include/assert.h.html#88" macro="true">assert(A.K >= InvalidTy && "ArgType cannot be pointer to invalid/unknown");
282    ArgType Res = A;
283    Res.Ptr = true;
284    return Res;
285  }
286
287  /// Create an ArgType which corresponds to the size_t/ssize_t type.
288  static ArgType makeSizeT(const ArgType &A) {
289    ArgType Res = A;
290    Res.TK = TypeKind::SizeT;
291    return Res;
292  }
293
294  /// Create an ArgType which corresponds to the ptrdiff_t/unsigned ptrdiff_t
295  /// type.
296  static ArgType makePtrdiffT(const ArgType &A) {
297    ArgType Res = A;
298    Res.TK = TypeKind::PtrdiffT;
299    return Res;
300  }
301
302  MatchKind matchesType(ASTContext &CQualType argTyconst;
303
304  QualType getRepresentativeType(ASTContext &Cconst;
305
306  ArgType makeVectorType(ASTContext &Cunsigned NumEltsconst;
307
308  std::string getRepresentativeTypeName(ASTContext &Cconst;
309};
310
311class OptionalAmount {
312public:
313  enum HowSpecified { NotSpecifiedConstantArgInvalid };
314
315  OptionalAmount(HowSpecified howSpecified,
316                 unsigned amount,
317                 const char *amountStart,
318                 unsigned amountLength,
319                 bool usesPositionalArg)
320  : start(amountStart), length(amountLength), hs(howSpecified), amt(amount),
321  UsesPositionalArg(usesPositionalArg), UsesDotPrefix(0) {}
322
323  OptionalAmount(bool valid = true)
324  : start(nullptr),length(0), hs(valid ? NotSpecified : Invalid), amt(0),
325  UsesPositionalArg(0), UsesDotPrefix(0) {}
326
327  explicit OptionalAmount(unsigned Amount)
328    : start(nullptr), length(0), hs(Constant), amt(Amount),
329    UsesPositionalArg(false), UsesDotPrefix(false) {}
330
331  bool isInvalid() const {
332    return hs == Invalid;
333  }
334
335  HowSpecified getHowSpecified() const { return hs; }
336  void setHowSpecified(HowSpecified h) { hs = h; }
337
338  bool hasDataArgument() const { return hs == Arg; }
339
340  unsigned getArgIndex() const {
341    assert(hasDataArgument());
342    return amt;
343  }
344
345  unsigned getConstantAmount() const {
346    assert(hs == Constant);
347    return amt;
348  }
349
350  const char *getStart() const {
351      // We include the . character if it is given.
352    return start - UsesDotPrefix;
353  }
354
355  unsigned getConstantLength() const {
356    assert(hs == Constant);
357    return length + UsesDotPrefix;
358  }
359
360  ArgType getArgType(ASTContext &Ctxconst;
361
362  void toString(raw_ostream &osconst;
363
364  bool usesPositionalArg() const { return (boolUsesPositionalArg; }
365  unsigned getPositionalArgIndex() const {
366    assert(hasDataArgument());
367    return amt + 1;
368  }
369
370  bool usesDotPrefix() const { return UsesDotPrefix; }
371  void setUsesDotPrefix() { UsesDotPrefix = true; }
372
373private:
374  const char *start;
375  unsigned length;
376  HowSpecified hs;
377  unsigned amt;
378  bool UsesPositionalArg : 1;
379  bool UsesDotPrefix;
380};
381
382
383class FormatSpecifier {
384protected:
385  LengthModifier LM;
386  OptionalAmount FieldWidth;
387  ConversionSpecifier CS;
388  OptionalAmount VectorNumElts;
389
390  /// Positional arguments, an IEEE extension:
391  ///  IEEE Std 1003.1, 2004 Edition
392  ///  http://www.opengroup.org/onlinepubs/009695399/functions/printf.html
393  bool UsesPositionalArg;
394  unsigned argIndex;
395public:
396  FormatSpecifier(bool isPrintf)
397    : CS(isPrintf), VectorNumElts(false),
398      UsesPositionalArg(false), argIndex(0) {}
399
400  void setLengthModifier(LengthModifier lm) {
401    LM = lm;
402  }
403
404  void setUsesPositionalArg() { UsesPositionalArg = true; }
405
406  void setArgIndex(unsigned i) {
407    argIndex = i;
408  }
409
410  unsigned getArgIndex() const {
411    return argIndex;
412  }
413
414  unsigned getPositionalArgIndex() const {
415    return argIndex + 1;
416  }
417
418  const LengthModifier &getLengthModifier() const {
419    return LM;
420  }
421
422  const OptionalAmount &getFieldWidth() const {
423    return FieldWidth;
424  }
425
426  void setVectorNumElts(const OptionalAmount &Amt) {
427    VectorNumElts = Amt;
428  }
429
430  const OptionalAmount &getVectorNumElts() const {
431    return VectorNumElts;
432  }
433
434  void setFieldWidth(const OptionalAmount &Amt) {
435    FieldWidth = Amt;
436  }
437
438  bool usesPositionalArg() const { return UsesPositionalArg; }
439
440  bool hasValidLengthModifier(const TargetInfo &Target,
441                              const LangOptions &LOconst;
442
443  bool hasStandardLengthModifier() const;
444
445  Optional<LengthModifiergetCorrectedLengthModifier() const;
446
447  bool hasStandardConversionSpecifier(const LangOptions &LangOptconst;
448
449  bool hasStandardLengthConversionCombination() const;
450
451  /// For a TypedefType QT, if it is a named integer type such as size_t,
452  /// assign the appropriate value to LM and return true.
453  static bool namedTypeToLengthModifier(QualType QTLengthModifier &LM);
454};
455
456// end analyze_format_string namespace
457
458//===----------------------------------------------------------------------===//
459/// Pieces specific to fprintf format strings.
460
461namespace analyze_printf {
462
463class PrintfConversionSpecifier :
464  public analyze_format_string::ConversionSpecifier  {
465public:
466  PrintfConversionSpecifier()
467    : ConversionSpecifier(truenullptrInvalidSpecifier) {}
468
469  PrintfConversionSpecifier(const char *posKind k)
470    : ConversionSpecifier(trueposk) {}
471
472  bool isObjCArg() const { return kind >= ObjCBeg && kind <= ObjCEnd; }
473  bool isDoubleArg() const { return kind >= DoubleArgBeg &&
474                                    kind <= DoubleArgEnd; }
475
476  static bool classof(const analyze_format_string::ConversionSpecifier *CS) {
477    return CS->isPrintfKind();
478  }
479};
480
481using analyze_format_string::ArgType;
482using analyze_format_string::LengthModifier;
483using analyze_format_string::OptionalAmount;
484using analyze_format_string::OptionalFlag;
485
486class PrintfSpecifier : public analyze_format_string::FormatSpecifier {
487  OptionalFlag HasThousandsGrouping// ''', POSIX extension.
488  OptionalFlag IsLeftJustified// '-'
489  OptionalFlag HasPlusPrefix// '+'
490  OptionalFlag HasSpacePrefix// ' '
491  OptionalFlag HasAlternativeForm// '#'
492  OptionalFlag HasLeadingZeroes// '0'
493  OptionalFlag HasObjCTechnicalTerm// '[tt]'
494  OptionalFlag IsPrivate;            // '{private}'
495  OptionalFlag IsPublic;             // '{public}'
496  OptionalFlag IsSensitive;          // '{sensitive}'
497  OptionalAmount Precision;
498  StringRef MaskType;
499
500  ArgType getScalarArgType(ASTContext &Ctxbool IsObjCLiteralconst;
501
502public:
503  PrintfSpecifier()
504      : FormatSpecifier(/* isPrintf = */ true), HasThousandsGrouping("'"),
505        IsLeftJustified("-"), HasPlusPrefix("+"), HasSpacePrefix(" "),
506        HasAlternativeForm("#"), HasLeadingZeroes("0"),
507        HasObjCTechnicalTerm("tt"), IsPrivate("private"), IsPublic("public"),
508        IsSensitive("sensitive") {}
509
510  static PrintfSpecifier Parse(const char *begconst char *end);
511
512    // Methods for incrementally constructing the PrintfSpecifier.
513  void setConversionSpecifier(const PrintfConversionSpecifier &cs) {
514    CS = cs;
515  }
516  void setHasThousandsGrouping(const char *position) {
517    HasThousandsGrouping.setPosition(position);
518  }
519  void setIsLeftJustified(const char *position) {
520    IsLeftJustified.setPosition(position);
521  }
522  void setHasPlusPrefix(const char *position) {
523    HasPlusPrefix.setPosition(position);
524  }
525  void setHasSpacePrefix(const char *position) {
526    HasSpacePrefix.setPosition(position);
527  }
528  void setHasAlternativeForm(const char *position) {
529    HasAlternativeForm.setPosition(position);
530  }
531  void setHasLeadingZeros(const char *position) {
532    HasLeadingZeroes.setPosition(position);
533  }
534  void setHasObjCTechnicalTerm(const char *position) {
535    HasObjCTechnicalTerm.setPosition(position);
536  }
537  void setIsPrivate(const char *position) { IsPrivate.setPosition(position); }
538  void setIsPublic(const char *position) { IsPublic.setPosition(position); }
539  void setIsSensitive(const char *position) {
540    IsSensitive.setPosition(position);
541  }
542  void setUsesPositionalArg() { UsesPositionalArg = true; }
543
544    // Methods for querying the format specifier.
545
546  const PrintfConversionSpecifier &getConversionSpecifier() const {
547    return cast<PrintfConversionSpecifier>(CS);
548  }
549
550  void setPrecision(const OptionalAmount &Amt) {
551    Precision = Amt;
552    Precision.setUsesDotPrefix();
553  }
554
555  const OptionalAmount &getPrecision() const {
556    return Precision;
557  }
558
559  bool consumesDataArgument() const {
560    return getConversionSpecifier().consumesDataArgument();
561  }
562
563  /// Returns the builtin type that a data argument
564  /// paired with this format specifier should have.  This method
565  /// will return null if the format specifier does not have
566  /// a matching data argument or the matching argument matches
567  /// more than one type.
568  ArgType getArgType(ASTContext &Ctxbool IsObjCLiteralconst;
569
570  const OptionalFlag &hasThousandsGrouping() const {
571      return HasThousandsGrouping;
572  }
573  const OptionalFlag &isLeftJustified() const { return IsLeftJustified; }
574  const OptionalFlag &hasPlusPrefix() const { return HasPlusPrefix; }
575  const OptionalFlag &hasAlternativeForm() const { return HasAlternativeForm; }
576  const OptionalFlag &hasLeadingZeros() const { return HasLeadingZeroes; }
577  const OptionalFlag &hasSpacePrefix() const { return HasSpacePrefix; }
578  const OptionalFlag &hasObjCTechnicalTerm() const { return HasObjCTechnicalTerm; }
579  const OptionalFlag &isPrivate() const { return IsPrivate; }
580  const OptionalFlag &isPublic() const { return IsPublic; }
581  const OptionalFlag &isSensitive() const { return IsSensitive; }
582  bool usesPositionalArg() const { return UsesPositionalArg; }
583
584  StringRef getMaskType() const { return MaskType; }
585  void setMaskType(StringRef S) { MaskType = S; }
586
587  /// Changes the specifier and length according to a QualType, retaining any
588  /// flags or options. Returns true on success, or false when a conversion
589  /// was not successful.
590  bool fixType(QualType QTconst LangOptions &LangOptASTContext &Ctx,
591               bool IsObjCLiteral);
592
593  void toString(raw_ostream &osconst;
594
595  // Validation methods - to check if any element results in undefined behavior
596  bool hasValidPlusPrefix() const;
597  bool hasValidAlternativeForm() const;
598  bool hasValidLeadingZeros() const;
599  bool hasValidSpacePrefix() const;
600  bool hasValidLeftJustified() const;
601  bool hasValidThousandsGroupingPrefix() const;
602
603  bool hasValidPrecision() const;
604  bool hasValidFieldWidth() const;
605};
606}  // end analyze_printf namespace
607
608//===----------------------------------------------------------------------===//
609/// Pieces specific to fscanf format strings.
610
611namespace analyze_scanf {
612
613class ScanfConversionSpecifier :
614    public analyze_format_string::ConversionSpecifier  {
615public:
616  ScanfConversionSpecifier()
617    : ConversionSpecifier(falsenullptrInvalidSpecifier) {}
618
619  ScanfConversionSpecifier(const char *posKind k)
620    : ConversionSpecifier(falseposk) {}
621
622  static bool classof(const analyze_format_string::ConversionSpecifier *CS) {
623    return !CS->isPrintfKind();
624  }
625};
626
627using analyze_format_string::ArgType;
628using analyze_format_string::LengthModifier;
629using analyze_format_string::OptionalAmount;
630using analyze_format_string::OptionalFlag;
631
632class ScanfSpecifier : public analyze_format_string::FormatSpecifier {
633  OptionalFlag SuppressAssignment// '*'
634public:
635  ScanfSpecifier() :
636    FormatSpecifier(/* isPrintf = */ false),
637    SuppressAssignment("*") {}
638
639  void setSuppressAssignment(const char *position) {
640    SuppressAssignment.setPosition(position);
641  }
642
643  const OptionalFlag &getSuppressAssignment() const {
644    return SuppressAssignment;
645  }
646
647  void setConversionSpecifier(const ScanfConversionSpecifier &cs) {
648    CS = cs;
649  }
650
651  const ScanfConversionSpecifier &getConversionSpecifier() const {
652    return cast<ScanfConversionSpecifier>(CS);
653  }
654
655  bool consumesDataArgument() const {
656    return CS.consumesDataArgument() && !SuppressAssignment;
657  }
658
659  ArgType getArgType(ASTContext &Ctxconst;
660
661  bool fixType(QualType QTQualType RawQTconst LangOptions &LangOpt,
662               ASTContext &Ctx);
663
664  void toString(raw_ostream &osconst;
665
666  static ScanfSpecifier Parse(const char *begconst char *end);
667};
668
669// end analyze_scanf namespace
670
671//===----------------------------------------------------------------------===//
672// Parsing and processing of format strings (both fprintf and fscanf).
673
674namespace analyze_format_string {
675
676enum PositionContext { FieldWidthPos = 0PrecisionPos = 1 };
677
678class FormatStringHandler {
679public:
680  FormatStringHandler() {}
681  virtual ~FormatStringHandler();
682
683  virtual void HandleNullChar(const char *nullCharacter) {}
684
685  virtual void HandlePosition(const char *startPosunsigned posLen) {}
686
687  virtual void HandleInvalidPosition(const char *startPosunsigned posLen,
688                                     PositionContext p) {}
689
690  virtual void HandleZeroPosition(const char *startPosunsigned posLen) {}
691
692  virtual void HandleIncompleteSpecifier(const char *startSpecifier,
693                                         unsigned specifierLen) {}
694
695  virtual void HandleEmptyObjCModifierFlag(const char *startFlags,
696                                           unsigned flagsLen) {}
697
698  virtual void HandleInvalidObjCModifierFlag(const char *startFlag,
699                                             unsigned flagLen) {}
700
701  virtual void HandleObjCFlagsWithNonObjCConversion(const char *flagsStart,
702                                            const char *flagsEnd,
703                                            const char *conversionPosition) {}
704  // Printf-specific handlers.
705
706  virtual bool HandleInvalidPrintfConversionSpecifier(
707                                      const analyze_printf::PrintfSpecifier &FS,
708                                      const char *startSpecifier,
709                                      unsigned specifierLen) {
710    return true;
711  }
712
713  virtual bool HandlePrintfSpecifier(const analyze_printf::PrintfSpecifier &FS,
714                                     const char *startSpecifier,
715                                     unsigned specifierLen) {
716    return true;
717  }
718
719  /// Handle mask types whose sizes are not between one and eight bytes.
720  virtual void handleInvalidMaskType(StringRef MaskType) {}
721
722    // Scanf-specific handlers.
723
724  virtual bool HandleInvalidScanfConversionSpecifier(
725                                        const analyze_scanf::ScanfSpecifier &FS,
726                                        const char *startSpecifier,
727                                        unsigned specifierLen) {
728    return true;
729  }
730
731  virtual bool HandleScanfSpecifier(const analyze_scanf::ScanfSpecifier &FS,
732                                    const char *startSpecifier,
733                                    unsigned specifierLen) {
734    return true;
735  }
736
737  virtual void HandleIncompleteScanList(const char *startconst char *end) {}
738};
739
740bool ParsePrintfString(FormatStringHandler &H,
741                       const char *begconst char *endconst LangOptions &LO,
742                       const TargetInfo &Targetbool isFreeBSDKPrintf);
743
744bool ParseFormatStringHasSArg(const char *begconst char *end,
745                              const LangOptions &LOconst TargetInfo &Target);
746
747bool ParseScanfString(FormatStringHandler &H,
748                      const char *begconst char *endconst LangOptions &LO,
749                      const TargetInfo &Target);
750
751// end analyze_format_string namespace
752// end clang namespace
753#endif
754
clang::analyze_format_string::OptionalFlag::isSet
clang::analyze_format_string::OptionalFlag::set
clang::analyze_format_string::OptionalFlag::clear
clang::analyze_format_string::OptionalFlag::setPosition
clang::analyze_format_string::OptionalFlag::getPosition
clang::analyze_format_string::OptionalFlag::toString
clang::analyze_format_string::OptionalFlag::representation
clang::analyze_format_string::OptionalFlag::position
clang::analyze_format_string::OptionalFlag::flag
clang::analyze_format_string::LengthModifier::Kind
clang::analyze_format_string::LengthModifier::getStart
clang::analyze_format_string::LengthModifier::getLength
clang::analyze_format_string::LengthModifier::getKind
clang::analyze_format_string::LengthModifier::setKind
clang::analyze_format_string::LengthModifier::toString
clang::analyze_format_string::LengthModifier::Position
clang::analyze_format_string::LengthModifier::kind
clang::analyze_format_string::ConversionSpecifier::Kind
clang::analyze_format_string::ConversionSpecifier::getStart
clang::analyze_format_string::ConversionSpecifier::getCharacters
clang::analyze_format_string::ConversionSpecifier::consumesDataArgument
clang::analyze_format_string::ConversionSpecifier::getKind
clang::analyze_format_string::ConversionSpecifier::setKind
clang::analyze_format_string::ConversionSpecifier::getLength
clang::analyze_format_string::ConversionSpecifier::setEndScanList
clang::analyze_format_string::ConversionSpecifier::isIntArg
clang::analyze_format_string::ConversionSpecifier::isUIntArg
clang::analyze_format_string::ConversionSpecifier::isAnyIntArg
clang::analyze_format_string::ConversionSpecifier::isDoubleArg
clang::analyze_format_string::ConversionSpecifier::toString
clang::analyze_format_string::ConversionSpecifier::isPrintfKind
clang::analyze_format_string::ConversionSpecifier::getStandardSpecifier
clang::analyze_format_string::ConversionSpecifier::IsPrintf
clang::analyze_format_string::ConversionSpecifier::Position
clang::analyze_format_string::ConversionSpecifier::EndScanList
clang::analyze_format_string::ConversionSpecifier::kind
clang::analyze_format_string::ArgType::Kind
clang::analyze_format_string::ArgType::MatchKind
clang::analyze_format_string::ArgType::K
clang::analyze_format_string::ArgType::T
clang::analyze_format_string::ArgType::Name
clang::analyze_format_string::ArgType::Ptr
clang::analyze_format_string::ArgType::TypeKind
clang::analyze_format_string::ArgType::TK
clang::analyze_format_string::ArgType::Invalid
clang::analyze_format_string::ArgType::isValid
clang::analyze_format_string::ArgType::isSizeT
clang::analyze_format_string::ArgType::isPtrdiffT
clang::analyze_format_string::ArgType::PtrTo
clang::analyze_format_string::ArgType::makeSizeT
clang::analyze_format_string::ArgType::makePtrdiffT
clang::analyze_format_string::ArgType::matchesType
clang::analyze_format_string::ArgType::getRepresentativeType
clang::analyze_format_string::ArgType::makeVectorType
clang::analyze_format_string::ArgType::getRepresentativeTypeName
clang::analyze_format_string::OptionalAmount::HowSpecified
clang::analyze_format_string::OptionalAmount::isInvalid
clang::analyze_format_string::OptionalAmount::getHowSpecified
clang::analyze_format_string::OptionalAmount::setHowSpecified
clang::analyze_format_string::OptionalAmount::hasDataArgument
clang::analyze_format_string::OptionalAmount::getArgIndex
clang::analyze_format_string::OptionalAmount::getConstantAmount
clang::analyze_format_string::OptionalAmount::getStart
clang::analyze_format_string::OptionalAmount::getConstantLength
clang::analyze_format_string::OptionalAmount::getArgType
clang::analyze_format_string::OptionalAmount::toString
clang::analyze_format_string::OptionalAmount::usesPositionalArg
clang::analyze_format_string::OptionalAmount::getPositionalArgIndex
clang::analyze_format_string::OptionalAmount::usesDotPrefix
clang::analyze_format_string::OptionalAmount::setUsesDotPrefix
clang::analyze_format_string::OptionalAmount::start
clang::analyze_format_string::OptionalAmount::length
clang::analyze_format_string::OptionalAmount::hs
clang::analyze_format_string::OptionalAmount::amt
clang::analyze_format_string::OptionalAmount::UsesPositionalArg
clang::analyze_format_string::OptionalAmount::UsesDotPrefix
clang::analyze_format_string::FormatSpecifier::LM
clang::analyze_format_string::FormatSpecifier::FieldWidth
clang::analyze_format_string::FormatSpecifier::CS
clang::analyze_format_string::FormatSpecifier::VectorNumElts
clang::analyze_format_string::FormatSpecifier::UsesPositionalArg
clang::analyze_format_string::FormatSpecifier::argIndex
clang::analyze_format_string::FormatSpecifier::setLengthModifier
clang::analyze_format_string::FormatSpecifier::setUsesPositionalArg
clang::analyze_format_string::FormatSpecifier::setArgIndex
clang::analyze_format_string::FormatSpecifier::getArgIndex
clang::analyze_format_string::FormatSpecifier::getPositionalArgIndex
clang::analyze_format_string::FormatSpecifier::getLengthModifier
clang::analyze_format_string::FormatSpecifier::getFieldWidth
clang::analyze_format_string::FormatSpecifier::setVectorNumElts
clang::analyze_format_string::FormatSpecifier::getVectorNumElts
clang::analyze_format_string::FormatSpecifier::setFieldWidth
clang::analyze_format_string::FormatSpecifier::usesPositionalArg
clang::analyze_format_string::FormatSpecifier::hasValidLengthModifier
clang::analyze_format_string::FormatSpecifier::hasStandardLengthModifier
clang::analyze_format_string::FormatSpecifier::getCorrectedLengthModifier
clang::analyze_format_string::FormatSpecifier::hasStandardConversionSpecifier
clang::analyze_format_string::FormatSpecifier::hasStandardLengthConversionCombination
clang::analyze_format_string::FormatSpecifier::namedTypeToLengthModifier
clang::analyze_printf::PrintfConversionSpecifier::isObjCArg
clang::analyze_printf::PrintfConversionSpecifier::isDoubleArg
clang::analyze_printf::PrintfConversionSpecifier::classof
clang::analyze_printf::PrintfSpecifier::HasThousandsGrouping
clang::analyze_printf::PrintfSpecifier::IsLeftJustified
clang::analyze_printf::PrintfSpecifier::HasPlusPrefix
clang::analyze_printf::PrintfSpecifier::HasSpacePrefix
clang::analyze_printf::PrintfSpecifier::HasAlternativeForm
clang::analyze_printf::PrintfSpecifier::HasLeadingZeroes
clang::analyze_printf::PrintfSpecifier::HasObjCTechnicalTerm
clang::analyze_printf::PrintfSpecifier::IsPrivate
clang::analyze_printf::PrintfSpecifier::IsPublic
clang::analyze_printf::PrintfSpecifier::IsSensitive
clang::analyze_printf::PrintfSpecifier::Precision
clang::analyze_printf::PrintfSpecifier::MaskType
clang::analyze_printf::PrintfSpecifier::getScalarArgType
clang::analyze_printf::PrintfSpecifier::Parse
clang::analyze_printf::PrintfSpecifier::setConversionSpecifier
clang::analyze_printf::PrintfSpecifier::setHasThousandsGrouping
clang::analyze_printf::PrintfSpecifier::setIsLeftJustified
clang::analyze_printf::PrintfSpecifier::setHasPlusPrefix
clang::analyze_printf::PrintfSpecifier::setHasSpacePrefix
clang::analyze_printf::PrintfSpecifier::setHasAlternativeForm
clang::analyze_printf::PrintfSpecifier::setHasLeadingZeros
clang::analyze_printf::PrintfSpecifier::setHasObjCTechnicalTerm
clang::analyze_printf::PrintfSpecifier::setIsPrivate
clang::analyze_printf::PrintfSpecifier::setIsPublic
clang::analyze_printf::PrintfSpecifier::setIsSensitive
clang::analyze_printf::PrintfSpecifier::setUsesPositionalArg
clang::analyze_printf::PrintfSpecifier::getConversionSpecifier
clang::analyze_printf::PrintfSpecifier::setPrecision
clang::analyze_printf::PrintfSpecifier::getPrecision
clang::analyze_printf::PrintfSpecifier::consumesDataArgument
clang::analyze_printf::PrintfSpecifier::getArgType
clang::analyze_printf::PrintfSpecifier::hasThousandsGrouping
clang::analyze_printf::PrintfSpecifier::isLeftJustified
clang::analyze_printf::PrintfSpecifier::hasPlusPrefix
clang::analyze_printf::PrintfSpecifier::hasAlternativeForm
clang::analyze_printf::PrintfSpecifier::hasLeadingZeros
clang::analyze_printf::PrintfSpecifier::hasSpacePrefix
clang::analyze_printf::PrintfSpecifier::hasObjCTechnicalTerm
clang::analyze_printf::PrintfSpecifier::isPrivate
clang::analyze_printf::PrintfSpecifier::isPublic
clang::analyze_printf::PrintfSpecifier::isSensitive
clang::analyze_printf::PrintfSpecifier::usesPositionalArg
clang::analyze_printf::PrintfSpecifier::getMaskType
clang::analyze_printf::PrintfSpecifier::setMaskType
clang::analyze_printf::PrintfSpecifier::fixType
clang::analyze_printf::PrintfSpecifier::toString
clang::analyze_printf::PrintfSpecifier::hasValidPlusPrefix
clang::analyze_printf::PrintfSpecifier::hasValidAlternativeForm
clang::analyze_printf::PrintfSpecifier::hasValidLeadingZeros
clang::analyze_printf::PrintfSpecifier::hasValidSpacePrefix
clang::analyze_printf::PrintfSpecifier::hasValidLeftJustified
clang::analyze_printf::PrintfSpecifier::hasValidThousandsGroupingPrefix
clang::analyze_printf::PrintfSpecifier::hasValidPrecision
clang::analyze_printf::PrintfSpecifier::hasValidFieldWidth
clang::analyze_scanf::ScanfConversionSpecifier::classof
clang::analyze_scanf::ScanfSpecifier::SuppressAssignment
clang::analyze_scanf::ScanfSpecifier::setSuppressAssignment
clang::analyze_scanf::ScanfSpecifier::getSuppressAssignment
clang::analyze_scanf::ScanfSpecifier::setConversionSpecifier
clang::analyze_scanf::ScanfSpecifier::getConversionSpecifier
clang::analyze_scanf::ScanfSpecifier::consumesDataArgument
clang::analyze_scanf::ScanfSpecifier::getArgType
clang::analyze_scanf::ScanfSpecifier::fixType
clang::analyze_scanf::ScanfSpecifier::toString
clang::analyze_scanf::ScanfSpecifier::Parse
clang::analyze_format_string::FormatStringHandler::HandleNullChar
clang::analyze_format_string::FormatStringHandler::HandlePosition
clang::analyze_format_string::FormatStringHandler::HandleInvalidPosition
clang::analyze_format_string::FormatStringHandler::HandleZeroPosition
clang::analyze_format_string::FormatStringHandler::HandleIncompleteSpecifier
clang::analyze_format_string::FormatStringHandler::HandleEmptyObjCModifierFlag
clang::analyze_format_string::FormatStringHandler::HandleInvalidObjCModifierFlag
clang::analyze_format_string::FormatStringHandler::HandleObjCFlagsWithNonObjCConversion
clang::analyze_format_string::FormatStringHandler::HandleInvalidPrintfConversionSpecifier
clang::analyze_format_string::FormatStringHandler::HandlePrintfSpecifier
clang::analyze_format_string::FormatStringHandler::handleInvalidMaskType
clang::analyze_format_string::FormatStringHandler::HandleInvalidScanfConversionSpecifier
clang::analyze_format_string::FormatStringHandler::HandleScanfSpecifier
clang::analyze_format_string::FormatStringHandler::HandleIncompleteScanList