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