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 template <typename T> class SpecifierResult { 51 T FS; 52 const char *Start; 53 bool Stop; 54 public: 55 SpecifierResult(bool stop = false) Start(nullptr)56 : Start(nullptr), Stop(stop) {} SpecifierResult(const char * start,const T & fs)57 SpecifierResult(const char *start, 58 const T &fs) 59 : FS(fs), Start(start), Stop(false) {} 60 getStart()61 const char *getStart() const { return Start; } shouldStop()62 bool shouldStop() const { return Stop; } hasValue()63 bool hasValue() const { return Start != nullptr; } getValue()64 const T &getValue() const { 65 assert(hasValue()); 66 return FS; 67 } getValue()68 const T &getValue() { return FS; } 69 }; 70 71 } // end analyze_format_string namespace 72 } // end clang namespace 73 74 #endif 75