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