Home | History | Annotate | Line # | Download | only in AST
      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:
     30   UpdateOnReturn(T &valueToUpdate, const T &valueToCopy)
     31     : ValueToUpdate(valueToUpdate), ValueToCopy(valueToCopy) {}
     32 
     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)
     78   : Start(nullptr), Stop(stop) {}
     79   SpecifierResult(const char *start,
     80                   const T &fs)
     81   : FS(fs), Start(start), Stop(false) {}
     82 
     83   const char *getStart() const { return Start; }
     84   bool shouldStop() const { return Stop; }
     85   bool hasValue() const { return Start != nullptr; }
     86   const T &getValue() const {
     87     assert(hasValue());
     88     return FS;
     89   }
     90   const T &getValue() { return FS; }
     91 };
     92 
     93 } // end analyze_format_string namespace
     94 } // end clang namespace
     95 
     96 #endif
     97