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