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/FormatString.h"
19#include "clang/AST/Type.h"
20
21namespace clang {
22
23class LangOptions;
24
25template <typename T> class UpdateOnReturn {
26 T &ValueToUpdate;
27 const T &ValueToCopy;
28
29public:
30 UpdateOnReturn(T &valueToUpdate, const T &valueToCopy)
31 : ValueToUpdate(valueToUpdate), ValueToCopy(valueToCopy) {}
32
33 ~UpdateOnReturn() { ValueToUpdate = ValueToCopy; }
34};
35
36namespace analyze_format_string {
37
38OptionalAmount ParseAmount(const char *&Beg, const char *E);
39OptionalAmount ParseNonPositionAmount(const char *&Beg, const char *E,
40 unsigned &argIndex);
41
42OptionalAmount ParsePositionAmount(FormatStringHandler &H, const char *Start,
43 const char *&Beg, const char *E,
44 PositionContext p);
45
46bool ParseFieldWidth(FormatStringHandler &H, FormatSpecifier &CS,
47 const char *Start, const char *&Beg, const char *E,
48 unsigned *argIndex);
49
50bool ParseArgPosition(FormatStringHandler &H, FormatSpecifier &CS,
51 const char *Start, const char *&Beg, const char *E);
52
53bool ParseVectorModifier(FormatStringHandler &H, FormatSpecifier &FS,
54 const char *&Beg, const char *E,
55 const LangOptions &LO);
56
57/// Returns true if a LengthModifier was parsed and installed in the
58/// FormatSpecifier& argument, and false otherwise.
59bool ParseLengthModifier(FormatSpecifier &FS, const char *&Beg, const char *E,
60 const LangOptions &LO, bool IsScanf = false);
61
62/// Returns true if the invalid specifier in \p SpecifierBegin is a UTF-8
63/// string; check that it won't go further than \p FmtStrEnd and write
64/// up the total size in \p Len.
65bool ParseUTF8InvalidSpecifier(const char *SpecifierBegin,
66 const char *FmtStrEnd, unsigned &Len);
67
68template <typename T> class SpecifierResult {
69 T FS;
70 const char *Start;
71 bool Stop;
72
73public:
74 SpecifierResult(bool stop = false) : Start(nullptr), Stop(stop) {}
75 SpecifierResult(const char *start, const T &fs)
76 : FS(fs), Start(start), Stop(false) {}
77
78 const char *getStart() const { return Start; }
79 bool shouldStop() const { return Stop; }
80 bool hasValue() const { return Start != nullptr; }
81 const T &getValue() const {
82 assert(hasValue());
83 return FS;
84 }
85 const T &getValue() { return FS; }
86};
87
88} // namespace analyze_format_string
89} // namespace clang
90
91#endif
92