xref: /freebsd/contrib/llvm-project/clang/lib/AST/FormatStringParsing.h (revision 25ecdc7d52770caf1c9b44b5ec11f468f6b636f3)
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