aboutsummaryrefslogtreecommitdiff
path: root/clang/lib/Analysis/PrintfFormatString.cpp
diff options
context:
space:
mode:
authorTed Kremenek <kremenek@apple.com>2010-01-29 22:59:32 +0000
committerTed Kremenek <kremenek@apple.com>2010-01-29 22:59:32 +0000
commit79db7b7b170c35cbf6ae619235a843e29cba8183 (patch)
tree6fdbe0bf0130a03180bd5ac0ae8bd74bf5df2c6c /clang/lib/Analysis/PrintfFormatString.cpp
parent1b8453067bdc22441010ae5395238a43575cc171 (diff)
downloadllvm-79db7b7b170c35cbf6ae619235a843e29cba8183.zip
llvm-79db7b7b170c35cbf6ae619235a843e29cba8183.tar.gz
llvm-79db7b7b170c35cbf6ae619235a843e29cba8183.tar.bz2
Per a suggestion from Cristian Draghici, add a method to FormatSpecifier that returns the expected type of the matching data argument. It isn't complete, but should handle several of the important cases.
llvm-svn: 94851
Diffstat (limited to 'clang/lib/Analysis/PrintfFormatString.cpp')
-rw-r--r--clang/lib/Analysis/PrintfFormatString.cpp53
1 files changed, 53 insertions, 0 deletions
diff --git a/clang/lib/Analysis/PrintfFormatString.cpp b/clang/lib/Analysis/PrintfFormatString.cpp
index bb9ac84..6192c29 100644
--- a/clang/lib/Analysis/PrintfFormatString.cpp
+++ b/clang/lib/Analysis/PrintfFormatString.cpp
@@ -13,9 +13,11 @@
//===----------------------------------------------------------------------===//
#include "clang/Analysis/Analyses/PrintfFormatString.h"
+#include "clang/AST/ASTContext.h"
using clang::analyze_printf::FormatSpecifier;
using clang::analyze_printf::OptionalAmount;
+using clang::analyze_printf::ArgTypeResult;
using namespace clang;
namespace {
@@ -261,3 +263,54 @@ bool clang::ParseFormatString(FormatStringHandler &H,
}
FormatStringHandler::~FormatStringHandler() {}
+
+//===----------------------------------------------------------------------===//
+// Methods on FormatSpecifier.
+//===----------------------------------------------------------------------===//
+
+ArgTypeResult FormatSpecifier::getArgType(ASTContext &Ctx) const {
+ if (!CS.consumesDataArgument())
+ return ArgTypeResult::Invalid();
+
+ if (CS.isIntArg())
+ switch (LM) {
+ case AsLongDouble:
+ return ArgTypeResult::Invalid();
+ case None: return Ctx.IntTy;
+ case AsChar: return Ctx.SignedCharTy;
+ case AsShort: return Ctx.ShortTy;
+ case AsLong: return Ctx.LongTy;
+ case AsLongLong: return Ctx.LongLongTy;
+ case AsIntMax:
+ // FIXME: Return unknown for now.
+ return ArgTypeResult();
+ case AsSizeT: return Ctx.getSizeType();
+ case AsPtrDiff: return Ctx.getPointerDiffType();
+ }
+
+ if (CS.isUIntArg())
+ switch (LM) {
+ case AsLongDouble:
+ return ArgTypeResult::Invalid();
+ case None: return Ctx.UnsignedIntTy;
+ case AsChar: return Ctx.UnsignedCharTy;
+ case AsShort: return Ctx.UnsignedShortTy;
+ case AsLong: return Ctx.UnsignedLongTy;
+ case AsLongLong: return Ctx.UnsignedLongLongTy;
+ case AsIntMax:
+ // FIXME: Return unknown for now.
+ return ArgTypeResult();
+ case AsSizeT:
+ // FIXME: How to get the corresponding unsigned
+ // version of size_t?
+ return ArgTypeResult();
+ case AsPtrDiff:
+ // FIXME: How to get the corresponding unsigned
+ // version of ptrdiff_t?
+ return ArgTypeResult();
+ }
+
+ // FIXME: Handle other cases.
+ return ArgTypeResult();
+}
+