Home | History | Annotate | Download | only in Analysis
      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:
     18   UpdateOnReturn(T &valueToUpdate, const T &valueToCopy)
     19     : ValueToUpdate(valueToUpdate), ValueToCopy(valueToCopy) {}
     20 
     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)
     62   : Start(nullptr), Stop(stop) {}
     63   SpecifierResult(const char *start,
     64                   const T &fs)
     65   : FS(fs), Start(start), Stop(false) {}
     66 
     67   const char *getStart() const { return Start; }
     68   bool shouldStop() const { return Stop; }
     69   bool hasValue() const { return Start != nullptr; }
     70   const T &getValue() const {
     71     assert(hasValue());
     72     return FS;
     73   }
     74   const T &getValue() { return FS; }
     75 };
     76 
     77 } // end analyze_format_string namespace
     78 } // end clang namespace
     79 
     80 #endif
     81