1#ifndef LLVM_CLANG_FORMAT_PARSING_H
2#define LLVM_CLANG_FORMAT_PARSING_H
3
4#include "clang/AST/ASTContext.h"
5#include "clang/AST/Type.h"
6#include "clang/Analysis/Analyses/FormatString.h"
7#include "llvm/Support/raw_ostream.h"
8
9namespace clang {
10
11class LangOptions;
12
13template <typename T>
14class UpdateOnReturn {
15  T &ValueToUpdate;
16  const T &ValueToCopy;
17public:
18  UpdateOnReturn(T &valueToUpdate, const T &valueToCopy)
19    : ValueToUpdate(valueToUpdate), ValueToCopy(valueToCopy) {}
20
21  ~UpdateOnReturn() {
22    ValueToUpdate = ValueToCopy;
23  }
24};
25
26namespace analyze_format_string {
27
28OptionalAmount ParseAmount(const char *&Beg, const char *E);
29OptionalAmount ParseNonPositionAmount(const char *&Beg, const char *E,
30                                      unsigned &argIndex);
31
32OptionalAmount ParsePositionAmount(FormatStringHandler &H,
33                                   const char *Start, const char *&Beg,
34                                   const char *E, PositionContext p);
35
36bool ParseFieldWidth(FormatStringHandler &H,
37                     FormatSpecifier &CS,
38                     const char *Start, const char *&Beg, const char *E,
39                     unsigned *argIndex);
40
41bool ParseArgPosition(FormatStringHandler &H,
42                      FormatSpecifier &CS, const char *Start,
43                      const char *&Beg, const char *E);
44
45/// Returns true if a LengthModifier was parsed and installed in the
46/// FormatSpecifier& argument, and false otherwise.
47bool ParseLengthModifier(FormatSpecifier &FS, const char *&Beg, const char *E,
48                         const LangOptions &LO, bool IsScanf = false);
49
50template <typename T> class SpecifierResult {
51  T FS;
52  const char *Start;
53  bool Stop;
54public:
55  SpecifierResult(bool stop = false)
56  : Start(nullptr), Stop(stop) {}
57  SpecifierResult(const char *start,
58                  const T &fs)
59  : FS(fs), Start(start), Stop(false) {}
60
61  const char *getStart() const { return Start; }
62  bool shouldStop() const { return Stop; }
63  bool hasValue() const { return Start != nullptr; }
64  const T &getValue() const {
65    assert(hasValue());
66    return FS;
67  }
68  const T &getValue() { return FS; }
69};
70
71} // end analyze_format_string namespace
72} // end clang namespace
73
74#endif
75