1 //===----- FormatStringParsing.h - Format String Parsing --------*- C++ -*-===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 // 9 // This provides some shared functions between printf and scanf format string 10 // parsing code. 11 // 12 //===----------------------------------------------------------------------===// 13 14 #ifndef LLVM_CLANG_LIB_ANALYSIS_FORMATSTRINGPARSING_H 15 #define LLVM_CLANG_LIB_ANALYSIS_FORMATSTRINGPARSING_H 16 17 #include "clang/AST/ASTContext.h" 18 #include "clang/AST/Type.h" 19 #include "clang/AST/FormatString.h" 20 21 namespace clang { 22 23 class LangOptions; 24 25 template <typename T> 26 class UpdateOnReturn { 27 T &ValueToUpdate; 28 const T &ValueToCopy; 29 public: UpdateOnReturn(T & valueToUpdate,const T & valueToCopy)30 UpdateOnReturn(T &valueToUpdate, const T &valueToCopy) 31 : ValueToUpdate(valueToUpdate), ValueToCopy(valueToCopy) {} 32 ~UpdateOnReturn()33 ~UpdateOnReturn() { 34 ValueToUpdate = ValueToCopy; 35 } 36 }; 37 38 namespace analyze_format_string { 39 40 OptionalAmount ParseAmount(const char *&Beg, const char *E); 41 OptionalAmount ParseNonPositionAmount(const char *&Beg, const char *E, 42 unsigned &argIndex); 43 44 OptionalAmount ParsePositionAmount(FormatStringHandler &H, 45 const char *Start, const char *&Beg, 46 const char *E, PositionContext p); 47 48 bool ParseFieldWidth(FormatStringHandler &H, 49 FormatSpecifier &CS, 50 const char *Start, const char *&Beg, const char *E, 51 unsigned *argIndex); 52 53 bool ParseArgPosition(FormatStringHandler &H, 54 FormatSpecifier &CS, const char *Start, 55 const char *&Beg, const char *E); 56 57 bool ParseVectorModifier(FormatStringHandler &H, 58 FormatSpecifier &FS, const char *&Beg, const char *E, 59 const LangOptions &LO); 60 61 /// Returns true if a LengthModifier was parsed and installed in the 62 /// FormatSpecifier& argument, and false otherwise. 63 bool ParseLengthModifier(FormatSpecifier &FS, const char *&Beg, const char *E, 64 const LangOptions &LO, bool IsScanf = false); 65 66 /// Returns true if the invalid specifier in \p SpecifierBegin is a UTF-8 67 /// string; check that it won't go further than \p FmtStrEnd and write 68 /// up the total size in \p Len. 69 bool ParseUTF8InvalidSpecifier(const char *SpecifierBegin, 70 const char *FmtStrEnd, unsigned &Len); 71 72 template <typename T> class SpecifierResult { 73 T FS; 74 const char *Start; 75 bool Stop; 76 public: 77 SpecifierResult(bool stop = false) Start(nullptr)78 : Start(nullptr), Stop(stop) {} SpecifierResult(const char * start,const T & fs)79 SpecifierResult(const char *start, 80 const T &fs) 81 : FS(fs), Start(start), Stop(false) {} 82 getStart()83 const char *getStart() const { return Start; } shouldStop()84 bool shouldStop() const { return Stop; } hasValue()85 bool hasValue() const { return Start != nullptr; } getValue()86 const T &getValue() const { 87 assert(hasValue()); 88 return FS; 89 } getValue()90 const T &getValue() { return FS; } 91 }; 92 93 } // end analyze_format_string namespace 94 } // end clang namespace 95 96 #endif 97