1212795Sdim#ifndef LLVM_CLANG_FORMAT_PARSING_H
2212795Sdim#define LLVM_CLANG_FORMAT_PARSING_H
3212795Sdim
4212795Sdim#include "clang/AST/ASTContext.h"
5212795Sdim#include "clang/AST/Type.h"
6249423Sdim#include "clang/Analysis/Analyses/FormatString.h"
7212795Sdim#include "llvm/Support/raw_ostream.h"
8212795Sdim
9212795Sdimnamespace clang {
10212795Sdim
11234353Sdimclass LangOptions;
12234353Sdim
13212795Sdimtemplate <typename T>
14212795Sdimclass UpdateOnReturn {
15212795Sdim  T &ValueToUpdate;
16212795Sdim  const T &ValueToCopy;
17212795Sdimpublic:
18212795Sdim  UpdateOnReturn(T &valueToUpdate, const T &valueToCopy)
19212795Sdim    : ValueToUpdate(valueToUpdate), ValueToCopy(valueToCopy) {}
20212795Sdim
21212795Sdim  ~UpdateOnReturn() {
22212795Sdim    ValueToUpdate = ValueToCopy;
23212795Sdim  }
24212795Sdim};
25212795Sdim
26212795Sdimnamespace analyze_format_string {
27212795Sdim
28212795SdimOptionalAmount ParseAmount(const char *&Beg, const char *E);
29212795SdimOptionalAmount ParseNonPositionAmount(const char *&Beg, const char *E,
30212795Sdim                                      unsigned &argIndex);
31212795Sdim
32212795SdimOptionalAmount ParsePositionAmount(FormatStringHandler &H,
33212795Sdim                                   const char *Start, const char *&Beg,
34212795Sdim                                   const char *E, PositionContext p);
35212795Sdim
36212795Sdimbool ParseFieldWidth(FormatStringHandler &H,
37212795Sdim                     FormatSpecifier &CS,
38212795Sdim                     const char *Start, const char *&Beg, const char *E,
39212795Sdim                     unsigned *argIndex);
40212795Sdim
41212795Sdimbool ParseArgPosition(FormatStringHandler &H,
42212795Sdim                      FormatSpecifier &CS, const char *Start,
43212795Sdim                      const char *&Beg, const char *E);
44212795Sdim
45212795Sdim/// Returns true if a LengthModifier was parsed and installed in the
46212795Sdim/// FormatSpecifier& argument, and false otherwise.
47234353Sdimbool ParseLengthModifier(FormatSpecifier &FS, const char *&Beg, const char *E,
48234353Sdim                         const LangOptions &LO, bool IsScanf = false);
49212795Sdim
50212795Sdimtemplate <typename T> class SpecifierResult {
51212795Sdim  T FS;
52212795Sdim  const char *Start;
53212795Sdim  bool Stop;
54212795Sdimpublic:
55212795Sdim  SpecifierResult(bool stop = false)
56212795Sdim  : Start(0), Stop(stop) {}
57212795Sdim  SpecifierResult(const char *start,
58212795Sdim                  const T &fs)
59212795Sdim  : FS(fs), Start(start), Stop(false) {}
60212795Sdim
61212795Sdim  const char *getStart() const { return Start; }
62212795Sdim  bool shouldStop() const { return Stop; }
63212795Sdim  bool hasValue() const { return Start != 0; }
64212795Sdim  const T &getValue() const {
65212795Sdim    assert(hasValue());
66212795Sdim    return FS;
67212795Sdim  }
68212795Sdim  const T &getValue() { return FS; }
69212795Sdim};
70212795Sdim
71212795Sdim} // end analyze_format_string namespace
72212795Sdim} // end clang namespace
73212795Sdim
74212795Sdim#endif
75