1*67e74705SXin Li #ifndef LLVM_CLANG_LIB_ANALYSIS_FORMATSTRINGPARSING_H 2*67e74705SXin Li #define LLVM_CLANG_LIB_ANALYSIS_FORMATSTRINGPARSING_H 3*67e74705SXin Li 4*67e74705SXin Li #include "clang/AST/ASTContext.h" 5*67e74705SXin Li #include "clang/AST/Type.h" 6*67e74705SXin Li #include "clang/Analysis/Analyses/FormatString.h" 7*67e74705SXin Li #include "llvm/Support/raw_ostream.h" 8*67e74705SXin Li 9*67e74705SXin Li namespace clang { 10*67e74705SXin Li 11*67e74705SXin Li class LangOptions; 12*67e74705SXin Li 13*67e74705SXin Li template <typename T> 14*67e74705SXin Li class UpdateOnReturn { 15*67e74705SXin Li T &ValueToUpdate; 16*67e74705SXin Li const T &ValueToCopy; 17*67e74705SXin Li public: UpdateOnReturn(T & valueToUpdate,const T & valueToCopy)18*67e74705SXin Li UpdateOnReturn(T &valueToUpdate, const T &valueToCopy) 19*67e74705SXin Li : ValueToUpdate(valueToUpdate), ValueToCopy(valueToCopy) {} 20*67e74705SXin Li ~UpdateOnReturn()21*67e74705SXin Li ~UpdateOnReturn() { 22*67e74705SXin Li ValueToUpdate = ValueToCopy; 23*67e74705SXin Li } 24*67e74705SXin Li }; 25*67e74705SXin Li 26*67e74705SXin Li namespace analyze_format_string { 27*67e74705SXin Li 28*67e74705SXin Li OptionalAmount ParseAmount(const char *&Beg, const char *E); 29*67e74705SXin Li OptionalAmount ParseNonPositionAmount(const char *&Beg, const char *E, 30*67e74705SXin Li unsigned &argIndex); 31*67e74705SXin Li 32*67e74705SXin Li OptionalAmount ParsePositionAmount(FormatStringHandler &H, 33*67e74705SXin Li const char *Start, const char *&Beg, 34*67e74705SXin Li const char *E, PositionContext p); 35*67e74705SXin Li 36*67e74705SXin Li bool ParseFieldWidth(FormatStringHandler &H, 37*67e74705SXin Li FormatSpecifier &CS, 38*67e74705SXin Li const char *Start, const char *&Beg, const char *E, 39*67e74705SXin Li unsigned *argIndex); 40*67e74705SXin Li 41*67e74705SXin Li bool ParseArgPosition(FormatStringHandler &H, 42*67e74705SXin Li FormatSpecifier &CS, const char *Start, 43*67e74705SXin Li const char *&Beg, const char *E); 44*67e74705SXin Li 45*67e74705SXin Li /// Returns true if a LengthModifier was parsed and installed in the 46*67e74705SXin Li /// FormatSpecifier& argument, and false otherwise. 47*67e74705SXin Li bool ParseLengthModifier(FormatSpecifier &FS, const char *&Beg, const char *E, 48*67e74705SXin Li const LangOptions &LO, bool IsScanf = false); 49*67e74705SXin Li 50*67e74705SXin Li /// Returns true if the invalid specifier in \p SpecifierBegin is a UTF-8 51*67e74705SXin Li /// string; check that it won't go further than \p FmtStrEnd and write 52*67e74705SXin Li /// up the total size in \p Len. 53*67e74705SXin Li bool ParseUTF8InvalidSpecifier(const char *SpecifierBegin, 54*67e74705SXin Li const char *FmtStrEnd, unsigned &Len); 55*67e74705SXin Li 56*67e74705SXin Li template <typename T> class SpecifierResult { 57*67e74705SXin Li T FS; 58*67e74705SXin Li const char *Start; 59*67e74705SXin Li bool Stop; 60*67e74705SXin Li public: 61*67e74705SXin Li SpecifierResult(bool stop = false) Start(nullptr)62*67e74705SXin Li : Start(nullptr), Stop(stop) {} SpecifierResult(const char * start,const T & fs)63*67e74705SXin Li SpecifierResult(const char *start, 64*67e74705SXin Li const T &fs) 65*67e74705SXin Li : FS(fs), Start(start), Stop(false) {} 66*67e74705SXin Li getStart()67*67e74705SXin Li const char *getStart() const { return Start; } shouldStop()68*67e74705SXin Li bool shouldStop() const { return Stop; } hasValue()69*67e74705SXin Li bool hasValue() const { return Start != nullptr; } getValue()70*67e74705SXin Li const T &getValue() const { 71*67e74705SXin Li assert(hasValue()); 72*67e74705SXin Li return FS; 73*67e74705SXin Li } getValue()74*67e74705SXin Li const T &getValue() { return FS; } 75*67e74705SXin Li }; 76*67e74705SXin Li 77*67e74705SXin Li } // end analyze_format_string namespace 78*67e74705SXin Li } // end clang namespace 79*67e74705SXin Li 80*67e74705SXin Li #endif 81