blob: 17fd2f6aefb8ac72252963a0ac7e3322f0aba964 [file] [log] [blame]
Benjamin Kramer2f5db8b2014-08-13 16:25:19 +00001#ifndef LLVM_CLANG_LIB_ANALYSIS_FORMATSTRINGPARSING_H
2#define LLVM_CLANG_LIB_ANALYSIS_FORMATSTRINGPARSING_H
Ted Kremenek575e89d2010-07-16 02:11:26 +00003
Ted Kremenek575e89d2010-07-16 02:11:26 +00004#include "clang/AST/ASTContext.h"
5#include "clang/AST/Type.h"
Chandler Carruth3a022472012-12-04 09:13:33 +00006#include "clang/Analysis/Analyses/FormatString.h"
Ted Kremenek575e89d2010-07-16 02:11:26 +00007
Dan Gohman28ade552010-07-26 21:25:24 +00008namespace clang {
9
Hans Wennborg23926bd2011-12-15 10:25:47 +000010class LangOptions;
11
Ted Kremenek575e89d2010-07-16 02:11:26 +000012template <typename T>
13class UpdateOnReturn {
14 T &ValueToUpdate;
15 const T &ValueToCopy;
16public:
17 UpdateOnReturn(T &valueToUpdate, const T &valueToCopy)
18 : ValueToUpdate(valueToUpdate), ValueToCopy(valueToCopy) {}
19
20 ~UpdateOnReturn() {
21 ValueToUpdate = ValueToCopy;
22 }
23};
24
Ted Kremenek575e89d2010-07-16 02:11:26 +000025namespace analyze_format_string {
26
27OptionalAmount ParseAmount(const char *&Beg, const char *E);
28OptionalAmount ParseNonPositionAmount(const char *&Beg, const char *E,
29 unsigned &argIndex);
30
31OptionalAmount ParsePositionAmount(FormatStringHandler &H,
32 const char *Start, const char *&Beg,
33 const char *E, PositionContext p);
34
35bool ParseFieldWidth(FormatStringHandler &H,
36 FormatSpecifier &CS,
37 const char *Start, const char *&Beg, const char *E,
38 unsigned *argIndex);
39
40bool ParseArgPosition(FormatStringHandler &H,
41 FormatSpecifier &CS, const char *Start,
42 const char *&Beg, const char *E);
43
44/// Returns true if a LengthModifier was parsed and installed in the
45/// FormatSpecifier& argument, and false otherwise.
Hans Wennborg23926bd2011-12-15 10:25:47 +000046bool ParseLengthModifier(FormatSpecifier &FS, const char *&Beg, const char *E,
47 const LangOptions &LO, bool IsScanf = false);
Bruno Cardoso Lopes0c18d032016-03-29 17:35:02 +000048
49/// Returns true if the invalid specifier in \p SpecifierBegin is a UTF-8
50/// string; check that it won't go further than \p FmtStrEnd and write
51/// up the total size in \p Len.
52bool ParseUTF8InvalidSpecifier(const char *SpecifierBegin,
53 const char *FmtStrEnd, unsigned &Len);
54
Ted Kremenek575e89d2010-07-16 02:11:26 +000055template <typename T> class SpecifierResult {
56 T FS;
57 const char *Start;
58 bool Stop;
59public:
60 SpecifierResult(bool stop = false)
Craig Topper25542942014-05-20 04:30:07 +000061 : Start(nullptr), Stop(stop) {}
Ted Kremenek575e89d2010-07-16 02:11:26 +000062 SpecifierResult(const char *start,
63 const T &fs)
64 : FS(fs), Start(start), Stop(false) {}
65
66 const char *getStart() const { return Start; }
67 bool shouldStop() const { return Stop; }
Craig Topper25542942014-05-20 04:30:07 +000068 bool hasValue() const { return Start != nullptr; }
Ted Kremenek575e89d2010-07-16 02:11:26 +000069 const T &getValue() const {
70 assert(hasValue());
71 return FS;
72 }
73 const T &getValue() { return FS; }
74};
75
Alexander Kornienkoab9db512015-06-22 23:07:51 +000076} // end analyze_format_string namespace
77} // end clang namespace
Ted Kremenek575e89d2010-07-16 02:11:26 +000078
79#endif