2014-08-14 00:25:19 +08:00
|
|
|
#ifndef LLVM_CLANG_LIB_ANALYSIS_FORMATSTRINGPARSING_H
|
|
|
|
#define LLVM_CLANG_LIB_ANALYSIS_FORMATSTRINGPARSING_H
|
2010-07-16 10:11:26 +08:00
|
|
|
|
|
|
|
#include "clang/AST/ASTContext.h"
|
|
|
|
#include "clang/AST/Type.h"
|
2012-12-04 17:13:33 +08:00
|
|
|
#include "clang/Analysis/Analyses/FormatString.h"
|
2010-07-16 10:11:26 +08:00
|
|
|
#include "llvm/Support/raw_ostream.h"
|
|
|
|
|
2010-07-27 05:25:24 +08:00
|
|
|
namespace clang {
|
|
|
|
|
2011-12-15 18:25:47 +08:00
|
|
|
class LangOptions;
|
|
|
|
|
2010-07-16 10:11:26 +08:00
|
|
|
template <typename T>
|
|
|
|
class UpdateOnReturn {
|
|
|
|
T &ValueToUpdate;
|
|
|
|
const T &ValueToCopy;
|
|
|
|
public:
|
|
|
|
UpdateOnReturn(T &valueToUpdate, const T &valueToCopy)
|
|
|
|
: ValueToUpdate(valueToUpdate), ValueToCopy(valueToCopy) {}
|
|
|
|
|
|
|
|
~UpdateOnReturn() {
|
|
|
|
ValueToUpdate = ValueToCopy;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
namespace analyze_format_string {
|
|
|
|
|
|
|
|
OptionalAmount ParseAmount(const char *&Beg, const char *E);
|
|
|
|
OptionalAmount ParseNonPositionAmount(const char *&Beg, const char *E,
|
|
|
|
unsigned &argIndex);
|
|
|
|
|
|
|
|
OptionalAmount ParsePositionAmount(FormatStringHandler &H,
|
|
|
|
const char *Start, const char *&Beg,
|
|
|
|
const char *E, PositionContext p);
|
|
|
|
|
|
|
|
bool ParseFieldWidth(FormatStringHandler &H,
|
|
|
|
FormatSpecifier &CS,
|
|
|
|
const char *Start, const char *&Beg, const char *E,
|
|
|
|
unsigned *argIndex);
|
|
|
|
|
|
|
|
bool ParseArgPosition(FormatStringHandler &H,
|
|
|
|
FormatSpecifier &CS, const char *Start,
|
|
|
|
const char *&Beg, const char *E);
|
|
|
|
|
|
|
|
/// Returns true if a LengthModifier was parsed and installed in the
|
|
|
|
/// FormatSpecifier& argument, and false otherwise.
|
2011-12-15 18:25:47 +08:00
|
|
|
bool ParseLengthModifier(FormatSpecifier &FS, const char *&Beg, const char *E,
|
|
|
|
const LangOptions &LO, bool IsScanf = false);
|
2016-03-30 01:35:02 +08:00
|
|
|
|
|
|
|
/// Returns true if the invalid specifier in \p SpecifierBegin is a UTF-8
|
|
|
|
/// string; check that it won't go further than \p FmtStrEnd and write
|
|
|
|
/// up the total size in \p Len.
|
|
|
|
bool ParseUTF8InvalidSpecifier(const char *SpecifierBegin,
|
|
|
|
const char *FmtStrEnd, unsigned &Len);
|
|
|
|
|
2010-07-16 10:11:26 +08:00
|
|
|
template <typename T> class SpecifierResult {
|
|
|
|
T FS;
|
|
|
|
const char *Start;
|
|
|
|
bool Stop;
|
|
|
|
public:
|
|
|
|
SpecifierResult(bool stop = false)
|
2014-05-20 12:30:07 +08:00
|
|
|
: Start(nullptr), Stop(stop) {}
|
2010-07-16 10:11:26 +08:00
|
|
|
SpecifierResult(const char *start,
|
|
|
|
const T &fs)
|
|
|
|
: FS(fs), Start(start), Stop(false) {}
|
|
|
|
|
|
|
|
const char *getStart() const { return Start; }
|
|
|
|
bool shouldStop() const { return Stop; }
|
2014-05-20 12:30:07 +08:00
|
|
|
bool hasValue() const { return Start != nullptr; }
|
2010-07-16 10:11:26 +08:00
|
|
|
const T &getValue() const {
|
|
|
|
assert(hasValue());
|
|
|
|
return FS;
|
|
|
|
}
|
|
|
|
const T &getValue() { return FS; }
|
|
|
|
};
|
|
|
|
|
2015-06-23 07:07:51 +08:00
|
|
|
} // end analyze_format_string namespace
|
|
|
|
} // end clang namespace
|
2010-07-16 10:11:26 +08:00
|
|
|
|
|
|
|
#endif
|