150
|
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
|