FormatStringParsing.h revision 360784
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
21namespace clang {
22
23class LangOptions;
24
25template <typename T>
26class UpdateOnReturn {
27  T &ValueToUpdate;
28  const T &ValueToCopy;
29public:
30  UpdateOnReturn(T &valueToUpdate, const T &valueToCopy)
31    : ValueToUpdate(valueToUpdate), ValueToCopy(valueToCopy) {}
32
33  ~UpdateOnReturn() {
34    ValueToUpdate = ValueToCopy;
35  }
36};
37
38namespace analyze_format_string {
39
40OptionalAmount ParseAmount(const char *&Beg, const char *E);
41OptionalAmount ParseNonPositionAmount(const char *&Beg, const char *E,
42                                      unsigned &argIndex);
43
44OptionalAmount ParsePositionAmount(FormatStringHandler &H,
45                                   const char *Start, const char *&Beg,
46                                   const char *E, PositionContext p);
47
48bool ParseFieldWidth(FormatStringHandler &H,
49                     FormatSpecifier &CS,
50                     const char *Start, const char *&Beg, const char *E,
51                     unsigned *argIndex);
52
53bool ParseArgPosition(FormatStringHandler &H,
54                      FormatSpecifier &CS, const char *Start,
55                      const char *&Beg, const char *E);
56
57bool 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.
63bool 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.
69bool ParseUTF8InvalidSpecifier(const char *SpecifierBegin,
70                               const char *FmtStrEnd, unsigned &Len);
71
72template <typename T> class SpecifierResult {
73  T FS;
74  const char *Start;
75  bool Stop;
76public:
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