123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785 |
- #pragma once
- #ifdef __GNUC__
- #pragma GCC diagnostic push
- #pragma GCC diagnostic ignored "-Wunused-parameter"
- #endif
- //= FormatString.h - Analysis of printf/fprintf format strings --*- C++ -*-===//
- //
- // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
- // See https://llvm.org/LICENSE.txt for license information.
- // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
- //
- //===----------------------------------------------------------------------===//
- //
- // This file defines APIs for analyzing the format strings of printf, fscanf,
- // and friends.
- //
- // The structure of format strings for fprintf are described in C99 7.19.6.1.
- //
- // The structure of format strings for fscanf are described in C99 7.19.6.2.
- //
- //===----------------------------------------------------------------------===//
- #ifndef LLVM_CLANG_AST_FORMATSTRING_H
- #define LLVM_CLANG_AST_FORMATSTRING_H
- #include "clang/AST/CanonicalType.h"
- namespace clang {
- class TargetInfo;
- //===----------------------------------------------------------------------===//
- /// Common components of both fprintf and fscanf format strings.
- namespace analyze_format_string {
- /// Class representing optional flags with location and representation
- /// information.
- class OptionalFlag {
- public:
- OptionalFlag(const char *Representation)
- : representation(Representation), flag(false) {}
- bool isSet() const { return flag; }
- void set() { flag = true; }
- void clear() { flag = false; }
- void setPosition(const char *position) {
- assert(position);
- flag = true;
- this->position = position;
- }
- const char *getPosition() const {
- assert(position);
- return position;
- }
- const char *toString() const { return representation; }
- // Overloaded operators for bool like qualities
- explicit operator bool() const { return flag; }
- OptionalFlag& operator=(const bool &rhs) {
- flag = rhs;
- return *this; // Return a reference to myself.
- }
- private:
- const char *representation;
- const char *position;
- bool flag;
- };
- /// Represents the length modifier in a format string in scanf/printf.
- class LengthModifier {
- public:
- enum Kind {
- None,
- AsChar, // 'hh'
- AsShort, // 'h'
- AsShortLong, // 'hl' (OpenCL float/int vector element)
- AsLong, // 'l'
- AsLongLong, // 'll'
- AsQuad, // 'q' (BSD, deprecated, for 64-bit integer types)
- AsIntMax, // 'j'
- AsSizeT, // 'z'
- AsPtrDiff, // 't'
- AsInt32, // 'I32' (MSVCRT, like __int32)
- AsInt3264, // 'I' (MSVCRT, like __int3264 from MIDL)
- AsInt64, // 'I64' (MSVCRT, like __int64)
- AsLongDouble, // 'L'
- AsAllocate, // for '%as', GNU extension to C90 scanf
- AsMAllocate, // for '%ms', GNU extension to scanf
- AsWide, // 'w' (MSVCRT, like l but only for c, C, s, S, or Z
- AsWideChar = AsLong // for '%ls', only makes sense for printf
- };
- LengthModifier()
- : Position(nullptr), kind(None) {}
- LengthModifier(const char *pos, Kind k)
- : Position(pos), kind(k) {}
- const char *getStart() const {
- return Position;
- }
- unsigned getLength() const {
- switch (kind) {
- default:
- return 1;
- case AsLongLong:
- case AsChar:
- return 2;
- case AsInt32:
- case AsInt64:
- return 3;
- case None:
- return 0;
- }
- }
- Kind getKind() const { return kind; }
- void setKind(Kind k) { kind = k; }
- const char *toString() const;
- private:
- const char *Position;
- Kind kind;
- };
- class ConversionSpecifier {
- public:
- enum Kind {
- InvalidSpecifier = 0,
- // C99 conversion specifiers.
- cArg,
- dArg,
- DArg, // Apple extension
- iArg,
- IntArgBeg = dArg,
- IntArgEnd = iArg,
- oArg,
- OArg, // Apple extension
- uArg,
- UArg, // Apple extension
- xArg,
- XArg,
- UIntArgBeg = oArg,
- UIntArgEnd = XArg,
- fArg,
- FArg,
- eArg,
- EArg,
- gArg,
- GArg,
- aArg,
- AArg,
- DoubleArgBeg = fArg,
- DoubleArgEnd = AArg,
- sArg,
- pArg,
- nArg,
- PercentArg,
- CArg,
- SArg,
- // Apple extension: P specifies to os_log that the data being pointed to is
- // to be copied by os_log. The precision indicates the number of bytes to
- // copy.
- PArg,
- // ** Printf-specific **
- ZArg, // MS extension
- // Objective-C specific specifiers.
- ObjCObjArg, // '@'
- ObjCBeg = ObjCObjArg,
- ObjCEnd = ObjCObjArg,
- // FreeBSD kernel specific specifiers.
- FreeBSDbArg,
- FreeBSDDArg,
- FreeBSDrArg,
- FreeBSDyArg,
- // GlibC specific specifiers.
- PrintErrno, // 'm'
- PrintfConvBeg = ObjCObjArg,
- PrintfConvEnd = PrintErrno,
- // ** Scanf-specific **
- ScanListArg, // '['
- ScanfConvBeg = ScanListArg,
- ScanfConvEnd = ScanListArg
- };
- ConversionSpecifier(bool isPrintf = true)
- : IsPrintf(isPrintf), Position(nullptr), EndScanList(nullptr),
- kind(InvalidSpecifier) {}
- ConversionSpecifier(bool isPrintf, const char *pos, Kind k)
- : IsPrintf(isPrintf), Position(pos), EndScanList(nullptr), kind(k) {}
- const char *getStart() const {
- return Position;
- }
- StringRef getCharacters() const {
- return StringRef(getStart(), getLength());
- }
- bool consumesDataArgument() const {
- switch (kind) {
- case PrintErrno:
- assert(IsPrintf);
- return false;
- case PercentArg:
- return false;
- case InvalidSpecifier:
- return false;
- default:
- return true;
- }
- }
- Kind getKind() const { return kind; }
- void setKind(Kind k) { kind = k; }
- unsigned getLength() const {
- return EndScanList ? EndScanList - Position : 1;
- }
- void setEndScanList(const char *pos) { EndScanList = pos; }
- bool isIntArg() const { return (kind >= IntArgBeg && kind <= IntArgEnd) ||
- kind == FreeBSDrArg || kind == FreeBSDyArg; }
- bool isUIntArg() const { return kind >= UIntArgBeg && kind <= UIntArgEnd; }
- bool isAnyIntArg() const { return kind >= IntArgBeg && kind <= UIntArgEnd; }
- bool isDoubleArg() const {
- return kind >= DoubleArgBeg && kind <= DoubleArgEnd;
- }
- const char *toString() const;
- bool isPrintfKind() const { return IsPrintf; }
- Optional<ConversionSpecifier> getStandardSpecifier() const;
- protected:
- bool IsPrintf;
- const char *Position;
- const char *EndScanList;
- Kind kind;
- };
- class ArgType {
- public:
- enum Kind { UnknownTy, InvalidTy, SpecificTy, ObjCPointerTy, CPointerTy,
- AnyCharTy, CStrTy, WCStrTy, WIntTy };
- /// How well a given conversion specifier matches its argument.
- enum MatchKind {
- /// The conversion specifier and the argument types are incompatible. For
- /// instance, "%d" and float.
- NoMatch = 0,
- /// The conversion specifier and the argument type are compatible. For
- /// instance, "%d" and _Bool.
- Match = 1,
- /// The conversion specifier and the argument type are disallowed by the C
- /// standard, but are in practice harmless. For instance, "%p" and int*.
- NoMatchPedantic,
- /// The conversion specifier and the argument type are compatible, but still
- /// seems likely to be an error. For instance, "%hd" and _Bool.
- NoMatchTypeConfusion,
- };
- private:
- const Kind K;
- QualType T;
- const char *Name = nullptr;
- bool Ptr = false;
- /// The TypeKind identifies certain well-known types like size_t and
- /// ptrdiff_t.
- enum class TypeKind { DontCare, SizeT, PtrdiffT };
- TypeKind TK = TypeKind::DontCare;
- public:
- ArgType(Kind K = UnknownTy, const char *N = nullptr) : K(K), Name(N) {}
- ArgType(QualType T, const char *N = nullptr) : K(SpecificTy), T(T), Name(N) {}
- ArgType(CanQualType T) : K(SpecificTy), T(T) {}
- static ArgType Invalid() { return ArgType(InvalidTy); }
- bool isValid() const { return K != InvalidTy; }
- bool isSizeT() const { return TK == TypeKind::SizeT; }
- bool isPtrdiffT() const { return TK == TypeKind::PtrdiffT; }
- /// Create an ArgType which corresponds to the type pointer to A.
- static ArgType PtrTo(const ArgType& A) {
- assert(A.K >= InvalidTy && "ArgType cannot be pointer to invalid/unknown");
- ArgType Res = A;
- Res.Ptr = true;
- return Res;
- }
- /// Create an ArgType which corresponds to the size_t/ssize_t type.
- static ArgType makeSizeT(const ArgType &A) {
- ArgType Res = A;
- Res.TK = TypeKind::SizeT;
- return Res;
- }
- /// Create an ArgType which corresponds to the ptrdiff_t/unsigned ptrdiff_t
- /// type.
- static ArgType makePtrdiffT(const ArgType &A) {
- ArgType Res = A;
- Res.TK = TypeKind::PtrdiffT;
- return Res;
- }
- MatchKind matchesType(ASTContext &C, QualType argTy) const;
- QualType getRepresentativeType(ASTContext &C) const;
- ArgType makeVectorType(ASTContext &C, unsigned NumElts) const;
- std::string getRepresentativeTypeName(ASTContext &C) const;
- };
- class OptionalAmount {
- public:
- enum HowSpecified { NotSpecified, Constant, Arg, Invalid };
- OptionalAmount(HowSpecified howSpecified,
- unsigned amount,
- const char *amountStart,
- unsigned amountLength,
- bool usesPositionalArg)
- : start(amountStart), length(amountLength), hs(howSpecified), amt(amount),
- UsesPositionalArg(usesPositionalArg), UsesDotPrefix(false) {}
- OptionalAmount(bool valid = true)
- : start(nullptr),length(0), hs(valid ? NotSpecified : Invalid), amt(0),
- UsesPositionalArg(false), UsesDotPrefix(false) {}
- explicit OptionalAmount(unsigned Amount)
- : start(nullptr), length(0), hs(Constant), amt(Amount),
- UsesPositionalArg(false), UsesDotPrefix(false) {}
- bool isInvalid() const {
- return hs == Invalid;
- }
- HowSpecified getHowSpecified() const { return hs; }
- void setHowSpecified(HowSpecified h) { hs = h; }
- bool hasDataArgument() const { return hs == Arg; }
- unsigned getArgIndex() const {
- assert(hasDataArgument());
- return amt;
- }
- unsigned getConstantAmount() const {
- assert(hs == Constant);
- return amt;
- }
- const char *getStart() const {
- // We include the . character if it is given.
- return start - UsesDotPrefix;
- }
- unsigned getConstantLength() const {
- assert(hs == Constant);
- return length + UsesDotPrefix;
- }
- ArgType getArgType(ASTContext &Ctx) const;
- void toString(raw_ostream &os) const;
- bool usesPositionalArg() const { return (bool) UsesPositionalArg; }
- unsigned getPositionalArgIndex() const {
- assert(hasDataArgument());
- return amt + 1;
- }
- bool usesDotPrefix() const { return UsesDotPrefix; }
- void setUsesDotPrefix() { UsesDotPrefix = true; }
- private:
- const char *start;
- unsigned length;
- HowSpecified hs;
- unsigned amt;
- bool UsesPositionalArg : 1;
- bool UsesDotPrefix;
- };
- class FormatSpecifier {
- protected:
- LengthModifier LM;
- OptionalAmount FieldWidth;
- ConversionSpecifier CS;
- OptionalAmount VectorNumElts;
- /// Positional arguments, an IEEE extension:
- /// IEEE Std 1003.1, 2004 Edition
- /// http://www.opengroup.org/onlinepubs/009695399/functions/printf.html
- bool UsesPositionalArg;
- unsigned argIndex;
- public:
- FormatSpecifier(bool isPrintf)
- : CS(isPrintf), VectorNumElts(false),
- UsesPositionalArg(false), argIndex(0) {}
- void setLengthModifier(LengthModifier lm) {
- LM = lm;
- }
- void setUsesPositionalArg() { UsesPositionalArg = true; }
- void setArgIndex(unsigned i) {
- argIndex = i;
- }
- unsigned getArgIndex() const {
- return argIndex;
- }
- unsigned getPositionalArgIndex() const {
- return argIndex + 1;
- }
- const LengthModifier &getLengthModifier() const {
- return LM;
- }
- const OptionalAmount &getFieldWidth() const {
- return FieldWidth;
- }
- void setVectorNumElts(const OptionalAmount &Amt) {
- VectorNumElts = Amt;
- }
- const OptionalAmount &getVectorNumElts() const {
- return VectorNumElts;
- }
- void setFieldWidth(const OptionalAmount &Amt) {
- FieldWidth = Amt;
- }
- bool usesPositionalArg() const { return UsesPositionalArg; }
- bool hasValidLengthModifier(const TargetInfo &Target,
- const LangOptions &LO) const;
- bool hasStandardLengthModifier() const;
- Optional<LengthModifier> getCorrectedLengthModifier() const;
- bool hasStandardConversionSpecifier(const LangOptions &LangOpt) const;
- bool hasStandardLengthConversionCombination() const;
- /// For a TypedefType QT, if it is a named integer type such as size_t,
- /// assign the appropriate value to LM and return true.
- static bool namedTypeToLengthModifier(QualType QT, LengthModifier &LM);
- };
- } // end analyze_format_string namespace
- //===----------------------------------------------------------------------===//
- /// Pieces specific to fprintf format strings.
- namespace analyze_printf {
- class PrintfConversionSpecifier :
- public analyze_format_string::ConversionSpecifier {
- public:
- PrintfConversionSpecifier()
- : ConversionSpecifier(true, nullptr, InvalidSpecifier) {}
- PrintfConversionSpecifier(const char *pos, Kind k)
- : ConversionSpecifier(true, pos, k) {}
- bool isObjCArg() const { return kind >= ObjCBeg && kind <= ObjCEnd; }
- bool isDoubleArg() const { return kind >= DoubleArgBeg &&
- kind <= DoubleArgEnd; }
- static bool classof(const analyze_format_string::ConversionSpecifier *CS) {
- return CS->isPrintfKind();
- }
- };
- using analyze_format_string::ArgType;
- using analyze_format_string::LengthModifier;
- using analyze_format_string::OptionalAmount;
- using analyze_format_string::OptionalFlag;
- class PrintfSpecifier : public analyze_format_string::FormatSpecifier {
- OptionalFlag HasThousandsGrouping; // ''', POSIX extension.
- OptionalFlag IsLeftJustified; // '-'
- OptionalFlag HasPlusPrefix; // '+'
- OptionalFlag HasSpacePrefix; // ' '
- OptionalFlag HasAlternativeForm; // '#'
- OptionalFlag HasLeadingZeroes; // '0'
- OptionalFlag HasObjCTechnicalTerm; // '[tt]'
- OptionalFlag IsPrivate; // '{private}'
- OptionalFlag IsPublic; // '{public}'
- OptionalFlag IsSensitive; // '{sensitive}'
- OptionalAmount Precision;
- StringRef MaskType;
- ArgType getScalarArgType(ASTContext &Ctx, bool IsObjCLiteral) const;
- public:
- PrintfSpecifier()
- : FormatSpecifier(/* isPrintf = */ true), HasThousandsGrouping("'"),
- IsLeftJustified("-"), HasPlusPrefix("+"), HasSpacePrefix(" "),
- HasAlternativeForm("#"), HasLeadingZeroes("0"),
- HasObjCTechnicalTerm("tt"), IsPrivate("private"), IsPublic("public"),
- IsSensitive("sensitive") {}
- static PrintfSpecifier Parse(const char *beg, const char *end);
- // Methods for incrementally constructing the PrintfSpecifier.
- void setConversionSpecifier(const PrintfConversionSpecifier &cs) {
- CS = cs;
- }
- void setHasThousandsGrouping(const char *position) {
- HasThousandsGrouping.setPosition(position);
- }
- void setIsLeftJustified(const char *position) {
- IsLeftJustified.setPosition(position);
- }
- void setHasPlusPrefix(const char *position) {
- HasPlusPrefix.setPosition(position);
- }
- void setHasSpacePrefix(const char *position) {
- HasSpacePrefix.setPosition(position);
- }
- void setHasAlternativeForm(const char *position) {
- HasAlternativeForm.setPosition(position);
- }
- void setHasLeadingZeros(const char *position) {
- HasLeadingZeroes.setPosition(position);
- }
- void setHasObjCTechnicalTerm(const char *position) {
- HasObjCTechnicalTerm.setPosition(position);
- }
- void setIsPrivate(const char *position) { IsPrivate.setPosition(position); }
- void setIsPublic(const char *position) { IsPublic.setPosition(position); }
- void setIsSensitive(const char *position) {
- IsSensitive.setPosition(position);
- }
- void setUsesPositionalArg() { UsesPositionalArg = true; }
- // Methods for querying the format specifier.
- const PrintfConversionSpecifier &getConversionSpecifier() const {
- return cast<PrintfConversionSpecifier>(CS);
- }
- void setPrecision(const OptionalAmount &Amt) {
- Precision = Amt;
- Precision.setUsesDotPrefix();
- }
- const OptionalAmount &getPrecision() const {
- return Precision;
- }
- bool consumesDataArgument() const {
- return getConversionSpecifier().consumesDataArgument();
- }
- /// Returns the builtin type that a data argument
- /// paired with this format specifier should have. This method
- /// will return null if the format specifier does not have
- /// a matching data argument or the matching argument matches
- /// more than one type.
- ArgType getArgType(ASTContext &Ctx, bool IsObjCLiteral) const;
- const OptionalFlag &hasThousandsGrouping() const {
- return HasThousandsGrouping;
- }
- const OptionalFlag &isLeftJustified() const { return IsLeftJustified; }
- const OptionalFlag &hasPlusPrefix() const { return HasPlusPrefix; }
- const OptionalFlag &hasAlternativeForm() const { return HasAlternativeForm; }
- const OptionalFlag &hasLeadingZeros() const { return HasLeadingZeroes; }
- const OptionalFlag &hasSpacePrefix() const { return HasSpacePrefix; }
- const OptionalFlag &hasObjCTechnicalTerm() const { return HasObjCTechnicalTerm; }
- const OptionalFlag &isPrivate() const { return IsPrivate; }
- const OptionalFlag &isPublic() const { return IsPublic; }
- const OptionalFlag &isSensitive() const { return IsSensitive; }
- bool usesPositionalArg() const { return UsesPositionalArg; }
- StringRef getMaskType() const { return MaskType; }
- void setMaskType(StringRef S) { MaskType = S; }
- /// Changes the specifier and length according to a QualType, retaining any
- /// flags or options. Returns true on success, or false when a conversion
- /// was not successful.
- bool fixType(QualType QT, const LangOptions &LangOpt, ASTContext &Ctx,
- bool IsObjCLiteral);
- void toString(raw_ostream &os) const;
- // Validation methods - to check if any element results in undefined behavior
- bool hasValidPlusPrefix() const;
- bool hasValidAlternativeForm() const;
- bool hasValidLeadingZeros() const;
- bool hasValidSpacePrefix() const;
- bool hasValidLeftJustified() const;
- bool hasValidThousandsGroupingPrefix() const;
- bool hasValidPrecision() const;
- bool hasValidFieldWidth() const;
- };
- } // end analyze_printf namespace
- //===----------------------------------------------------------------------===//
- /// Pieces specific to fscanf format strings.
- namespace analyze_scanf {
- class ScanfConversionSpecifier :
- public analyze_format_string::ConversionSpecifier {
- public:
- ScanfConversionSpecifier()
- : ConversionSpecifier(false, nullptr, InvalidSpecifier) {}
- ScanfConversionSpecifier(const char *pos, Kind k)
- : ConversionSpecifier(false, pos, k) {}
- static bool classof(const analyze_format_string::ConversionSpecifier *CS) {
- return !CS->isPrintfKind();
- }
- };
- using analyze_format_string::ArgType;
- using analyze_format_string::LengthModifier;
- using analyze_format_string::OptionalAmount;
- using analyze_format_string::OptionalFlag;
- class ScanfSpecifier : public analyze_format_string::FormatSpecifier {
- OptionalFlag SuppressAssignment; // '*'
- public:
- ScanfSpecifier() :
- FormatSpecifier(/* isPrintf = */ false),
- SuppressAssignment("*") {}
- void setSuppressAssignment(const char *position) {
- SuppressAssignment.setPosition(position);
- }
- const OptionalFlag &getSuppressAssignment() const {
- return SuppressAssignment;
- }
- void setConversionSpecifier(const ScanfConversionSpecifier &cs) {
- CS = cs;
- }
- const ScanfConversionSpecifier &getConversionSpecifier() const {
- return cast<ScanfConversionSpecifier>(CS);
- }
- bool consumesDataArgument() const {
- return CS.consumesDataArgument() && !SuppressAssignment;
- }
- ArgType getArgType(ASTContext &Ctx) const;
- bool fixType(QualType QT, QualType RawQT, const LangOptions &LangOpt,
- ASTContext &Ctx);
- void toString(raw_ostream &os) const;
- static ScanfSpecifier Parse(const char *beg, const char *end);
- };
- } // end analyze_scanf namespace
- //===----------------------------------------------------------------------===//
- // Parsing and processing of format strings (both fprintf and fscanf).
- namespace analyze_format_string {
- enum PositionContext { FieldWidthPos = 0, PrecisionPos = 1 };
- class FormatStringHandler {
- public:
- FormatStringHandler() {}
- virtual ~FormatStringHandler();
- virtual void HandleNullChar(const char *nullCharacter) {}
- virtual void HandlePosition(const char *startPos, unsigned posLen) {}
- virtual void HandleInvalidPosition(const char *startPos, unsigned posLen,
- PositionContext p) {}
- virtual void HandleZeroPosition(const char *startPos, unsigned posLen) {}
- virtual void HandleIncompleteSpecifier(const char *startSpecifier,
- unsigned specifierLen) {}
- virtual void HandleEmptyObjCModifierFlag(const char *startFlags,
- unsigned flagsLen) {}
- virtual void HandleInvalidObjCModifierFlag(const char *startFlag,
- unsigned flagLen) {}
- virtual void HandleObjCFlagsWithNonObjCConversion(const char *flagsStart,
- const char *flagsEnd,
- const char *conversionPosition) {}
- // Printf-specific handlers.
- virtual bool HandleInvalidPrintfConversionSpecifier(
- const analyze_printf::PrintfSpecifier &FS,
- const char *startSpecifier,
- unsigned specifierLen) {
- return true;
- }
- virtual bool HandlePrintfSpecifier(const analyze_printf::PrintfSpecifier &FS,
- const char *startSpecifier,
- unsigned specifierLen,
- const TargetInfo &Target) {
- return true;
- }
- /// Handle mask types whose sizes are not between one and eight bytes.
- virtual void handleInvalidMaskType(StringRef MaskType) {}
- // Scanf-specific handlers.
- virtual bool HandleInvalidScanfConversionSpecifier(
- const analyze_scanf::ScanfSpecifier &FS,
- const char *startSpecifier,
- unsigned specifierLen) {
- return true;
- }
- virtual bool HandleScanfSpecifier(const analyze_scanf::ScanfSpecifier &FS,
- const char *startSpecifier,
- unsigned specifierLen) {
- return true;
- }
- virtual void HandleIncompleteScanList(const char *start, const char *end) {}
- };
- bool ParsePrintfString(FormatStringHandler &H,
- const char *beg, const char *end, const LangOptions &LO,
- const TargetInfo &Target, bool isFreeBSDKPrintf);
- bool ParseFormatStringHasSArg(const char *beg, const char *end,
- const LangOptions &LO, const TargetInfo &Target);
- bool ParseScanfString(FormatStringHandler &H,
- const char *beg, const char *end, const LangOptions &LO,
- const TargetInfo &Target);
- /// Return true if the given string has at least one formatting specifier.
- bool parseFormatStringHasFormattingSpecifiers(const char *Begin,
- const char *End,
- const LangOptions &LO,
- const TargetInfo &Target);
- } // end analyze_format_string namespace
- } // end clang namespace
- #endif
- #ifdef __GNUC__
- #pragma GCC diagnostic pop
- #endif
|