1826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek//= FormatString.h - Analysis of printf/fprintf format strings --*- C++ -*-===// 2826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek// 3826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek// The LLVM Compiler Infrastructure 4826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek// 5826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek// This file is distributed under the University of Illinois Open Source 6826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek// License. See LICENSE.TXT for details. 7826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek// 8826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek//===----------------------------------------------------------------------===// 9826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek// 10826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek// This file defines APIs for analyzing the format strings of printf, fscanf, 11826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek// and friends. 12826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek// 13826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek// The structure of format strings for fprintf are described in C99 7.19.6.1. 14826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek// 15826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek// The structure of format strings for fscanf are described in C99 7.19.6.2. 16826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek// 17826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek//===----------------------------------------------------------------------===// 18826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek 19826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek#ifndef LLVM_CLANG_FORMAT_H 20826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek#define LLVM_CLANG_FORMAT_H 21826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek 22826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek#include "clang/AST/CanonicalType.h" 23826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek 24826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremeneknamespace clang { 25826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek 26bbb6bb4952b77e57b842b4d3096848123ae690e7Jordan Roseclass TargetInfo; 27bbb6bb4952b77e57b842b4d3096848123ae690e7Jordan Rose 28826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek//===----------------------------------------------------------------------===// 29826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek/// Common components of both fprintf and fscanf format strings. 30826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremeneknamespace analyze_format_string { 31826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek 32826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek/// Class representing optional flags with location and representation 33826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek/// information. 34826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenekclass OptionalFlag { 35826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenekpublic: 36826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek OptionalFlag(const char *Representation) 37826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek : representation(Representation), flag(false) {} 38826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek bool isSet() { return flag; } 39826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek void set() { flag = true; } 40826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek void clear() { flag = false; } 41826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek void setPosition(const char *position) { 42826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek assert(position); 43826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek this->position = position; 44826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek } 45826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek const char *getPosition() const { 46826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek assert(position); 47826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek return position; 48826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek } 49826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek const char *toString() const { return representation; } 50826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek 51826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek // Overloaded operators for bool like qualities 527247c88d1e41514a41085f83ebf03dd5220e054aDavid Blaikie LLVM_EXPLICIT operator bool() const { return flag; } 53826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek OptionalFlag& operator=(const bool &rhs) { 54826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek flag = rhs; 55826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek return *this; // Return a reference to myself. 56826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek } 57826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenekprivate: 58826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek const char *representation; 59826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek const char *position; 60826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek bool flag; 61826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek}; 62826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek 63826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek/// Represents the length modifier in a format string in scanf/printf. 64826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenekclass LengthModifier { 65826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenekpublic: 66826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek enum Kind { 67826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek None, 68826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek AsChar, // 'hh' 69826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek AsShort, // 'h' 70826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek AsLong, // 'l' 7132addd519c6699000ff79c387a1c87f0ab7c3698Hans Wennborg AsLongLong, // 'll' 72a76879eb4c75dbd9ec671558f0b8b79a28d4d747Hans Wennborg AsQuad, // 'q' (BSD, deprecated, for 64-bit integer types) 73826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek AsIntMax, // 'j' 74826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek AsSizeT, // 'z' 75826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek AsPtrDiff, // 't' 76826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek AsLongDouble, // 'L' 7737969b7e14d6a4dfd934ef6d3738cc90b832ec1dHans Wennborg AsAllocate, // for '%as', GNU extension to C90 scanf 7837969b7e14d6a4dfd934ef6d3738cc90b832ec1dHans Wennborg AsMAllocate, // for '%ms', GNU extension to scanf 79826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek AsWideChar = AsLong // for '%ls', only makes sense for printf 80826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek }; 81826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek 82826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek LengthModifier() 83826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek : Position(0), kind(None) {} 84826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek LengthModifier(const char *pos, Kind k) 85826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek : Position(pos), kind(k) {} 86826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek 87826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek const char *getStart() const { 88826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek return Position; 89826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek } 90826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek 91826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek unsigned getLength() const { 92826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek switch (kind) { 93826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek default: 94826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek return 1; 95826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek case AsLongLong: 96826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek case AsChar: 97826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek return 2; 98826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek case None: 99826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek return 0; 100826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek } 101826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek } 102826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek 103826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek Kind getKind() const { return kind; } 104826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek void setKind(Kind k) { kind = k; } 105826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek 106826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek const char *toString() const; 107826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek 108826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenekprivate: 109826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek const char *Position; 110826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek Kind kind; 111826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek}; 112ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie 1136ecb950c65329f8d6ce9ad0514632df35a5ab61fTed Kremenekclass ConversionSpecifier { 1146ecb950c65329f8d6ce9ad0514632df35a5ab61fTed Kremenekpublic: 1156ecb950c65329f8d6ce9ad0514632df35a5ab61fTed Kremenek enum Kind { 1166ecb950c65329f8d6ce9ad0514632df35a5ab61fTed Kremenek InvalidSpecifier = 0, 1176ecb950c65329f8d6ce9ad0514632df35a5ab61fTed Kremenek // C99 conversion specifiers. 1186ecb950c65329f8d6ce9ad0514632df35a5ab61fTed Kremenek cArg, 1196ecb950c65329f8d6ce9ad0514632df35a5ab61fTed Kremenek dArg, 120275b6f52c7bcafc1f3cf291813b5c60ee776965aJordan Rose DArg, // Apple extension 1216ecb950c65329f8d6ce9ad0514632df35a5ab61fTed Kremenek iArg, 1228be066e6733364cd34f25c4f7b7344f72aa23369Jordan Rose IntArgBeg = dArg, IntArgEnd = iArg, 123ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie 1246ecb950c65329f8d6ce9ad0514632df35a5ab61fTed Kremenek oArg, 125275b6f52c7bcafc1f3cf291813b5c60ee776965aJordan Rose OArg, // Apple extension 1266ecb950c65329f8d6ce9ad0514632df35a5ab61fTed Kremenek uArg, 127275b6f52c7bcafc1f3cf291813b5c60ee776965aJordan Rose UArg, // Apple extension 1286ecb950c65329f8d6ce9ad0514632df35a5ab61fTed Kremenek xArg, 1296ecb950c65329f8d6ce9ad0514632df35a5ab61fTed Kremenek XArg, 1306ecb950c65329f8d6ce9ad0514632df35a5ab61fTed Kremenek UIntArgBeg = oArg, UIntArgEnd = XArg, 131ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie 1326ecb950c65329f8d6ce9ad0514632df35a5ab61fTed Kremenek fArg, 1336ecb950c65329f8d6ce9ad0514632df35a5ab61fTed Kremenek FArg, 1346ecb950c65329f8d6ce9ad0514632df35a5ab61fTed Kremenek eArg, 1356ecb950c65329f8d6ce9ad0514632df35a5ab61fTed Kremenek EArg, 1366ecb950c65329f8d6ce9ad0514632df35a5ab61fTed Kremenek gArg, 1376ecb950c65329f8d6ce9ad0514632df35a5ab61fTed Kremenek GArg, 1386ecb950c65329f8d6ce9ad0514632df35a5ab61fTed Kremenek aArg, 1396ecb950c65329f8d6ce9ad0514632df35a5ab61fTed Kremenek AArg, 1406ecb950c65329f8d6ce9ad0514632df35a5ab61fTed Kremenek DoubleArgBeg = fArg, DoubleArgEnd = AArg, 141ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie 1426ecb950c65329f8d6ce9ad0514632df35a5ab61fTed Kremenek sArg, 1436ecb950c65329f8d6ce9ad0514632df35a5ab61fTed Kremenek pArg, 1446ecb950c65329f8d6ce9ad0514632df35a5ab61fTed Kremenek nArg, 1456ecb950c65329f8d6ce9ad0514632df35a5ab61fTed Kremenek PercentArg, 1466ecb950c65329f8d6ce9ad0514632df35a5ab61fTed Kremenek CArg, 1476ecb950c65329f8d6ce9ad0514632df35a5ab61fTed Kremenek SArg, 148ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie 1496ecb950c65329f8d6ce9ad0514632df35a5ab61fTed Kremenek // ** Printf-specific ** 150ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie 1516ecb950c65329f8d6ce9ad0514632df35a5ab61fTed Kremenek // Objective-C specific specifiers. 1526ecb950c65329f8d6ce9ad0514632df35a5ab61fTed Kremenek ObjCObjArg, // '@' 1536ecb950c65329f8d6ce9ad0514632df35a5ab61fTed Kremenek ObjCBeg = ObjCObjArg, ObjCEnd = ObjCObjArg, 154ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie 1556ecb950c65329f8d6ce9ad0514632df35a5ab61fTed Kremenek // GlibC specific specifiers. 1566ecb950c65329f8d6ce9ad0514632df35a5ab61fTed Kremenek PrintErrno, // 'm' 157ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie 158cfdcd3066521ee0fa9f303f3863c726943db37e5Ted Kremenek PrintfConvBeg = ObjCObjArg, PrintfConvEnd = PrintErrno, 159ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie 160ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie // ** Scanf-specific ** 161cfdcd3066521ee0fa9f303f3863c726943db37e5Ted Kremenek ScanListArg, // '[' 162cfdcd3066521ee0fa9f303f3863c726943db37e5Ted Kremenek ScanfConvBeg = ScanListArg, ScanfConvEnd = ScanListArg 1636ecb950c65329f8d6ce9ad0514632df35a5ab61fTed Kremenek }; 164ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie 165670941c28c0683ecc251dafdf093a71629625dc9Jordan Rose ConversionSpecifier(bool isPrintf = true) 166cfdcd3066521ee0fa9f303f3863c726943db37e5Ted Kremenek : IsPrintf(isPrintf), Position(0), EndScanList(0), kind(InvalidSpecifier) {} 167ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie 1686ecb950c65329f8d6ce9ad0514632df35a5ab61fTed Kremenek ConversionSpecifier(bool isPrintf, const char *pos, Kind k) 169cfdcd3066521ee0fa9f303f3863c726943db37e5Ted Kremenek : IsPrintf(isPrintf), Position(pos), EndScanList(0), kind(k) {} 170ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie 1716ecb950c65329f8d6ce9ad0514632df35a5ab61fTed Kremenek const char *getStart() const { 1726ecb950c65329f8d6ce9ad0514632df35a5ab61fTed Kremenek return Position; 1736ecb950c65329f8d6ce9ad0514632df35a5ab61fTed Kremenek } 174ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie 175686775deca8b8685eb90801495880e3abdd844c2Chris Lattner StringRef getCharacters() const { 176686775deca8b8685eb90801495880e3abdd844c2Chris Lattner return StringRef(getStart(), getLength()); 1776ecb950c65329f8d6ce9ad0514632df35a5ab61fTed Kremenek } 178ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie 179cfdcd3066521ee0fa9f303f3863c726943db37e5Ted Kremenek bool consumesDataArgument() const { 180cfdcd3066521ee0fa9f303f3863c726943db37e5Ted Kremenek switch (kind) { 181cfdcd3066521ee0fa9f303f3863c726943db37e5Ted Kremenek case PrintErrno: 182cfdcd3066521ee0fa9f303f3863c726943db37e5Ted Kremenek assert(IsPrintf); 183d39d23e610c2a7815515d60c5a538d65d05e8bdcRichard Smith return false; 184cfdcd3066521ee0fa9f303f3863c726943db37e5Ted Kremenek case PercentArg: 185cfdcd3066521ee0fa9f303f3863c726943db37e5Ted Kremenek return false; 186cfdcd3066521ee0fa9f303f3863c726943db37e5Ted Kremenek default: 187cfdcd3066521ee0fa9f303f3863c726943db37e5Ted Kremenek return true; 188cfdcd3066521ee0fa9f303f3863c726943db37e5Ted Kremenek } 189cfdcd3066521ee0fa9f303f3863c726943db37e5Ted Kremenek } 190ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie 1916ecb950c65329f8d6ce9ad0514632df35a5ab61fTed Kremenek Kind getKind() const { return kind; } 1926ecb950c65329f8d6ce9ad0514632df35a5ab61fTed Kremenek void setKind(Kind k) { kind = k; } 1936ecb950c65329f8d6ce9ad0514632df35a5ab61fTed Kremenek unsigned getLength() const { 194cfdcd3066521ee0fa9f303f3863c726943db37e5Ted Kremenek return EndScanList ? EndScanList - Position : 1; 1956ecb950c65329f8d6ce9ad0514632df35a5ab61fTed Kremenek } 196ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie 1978be066e6733364cd34f25c4f7b7344f72aa23369Jordan Rose bool isIntArg() const { return kind >= IntArgBeg && kind <= IntArgEnd; } 1986fcd932dfd6835f70cc00d6f7c6789793f6d7b66Hans Wennborg bool isUIntArg() const { return kind >= UIntArgBeg && kind <= UIntArgEnd; } 1998be066e6733364cd34f25c4f7b7344f72aa23369Jordan Rose bool isAnyIntArg() const { return kind >= IntArgBeg && kind <= UIntArgEnd; } 2006ecb950c65329f8d6ce9ad0514632df35a5ab61fTed Kremenek const char *toString() const; 201ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie 2026ecb950c65329f8d6ce9ad0514632df35a5ab61fTed Kremenek bool isPrintfKind() const { return IsPrintf; } 203670941c28c0683ecc251dafdf093a71629625dc9Jordan Rose 204dc84cd5efdd3430efb22546b4ac656aa0540b210David Blaikie Optional<ConversionSpecifier> getStandardSpecifier() const; 2056ecb950c65329f8d6ce9ad0514632df35a5ab61fTed Kremenek 2066ecb950c65329f8d6ce9ad0514632df35a5ab61fTed Kremenekprotected: 2076ecb950c65329f8d6ce9ad0514632df35a5ab61fTed Kremenek bool IsPrintf; 2086ecb950c65329f8d6ce9ad0514632df35a5ab61fTed Kremenek const char *Position; 209cfdcd3066521ee0fa9f303f3863c726943db37e5Ted Kremenek const char *EndScanList; 2106ecb950c65329f8d6ce9ad0514632df35a5ab61fTed Kremenek Kind kind; 2116ecb950c65329f8d6ce9ad0514632df35a5ab61fTed Kremenek}; 212826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek 213f3749f4168c5cee59627a681ca4ca6e4116d0761Hans Wennborgclass ArgType { 214826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenekpublic: 215826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek enum Kind { UnknownTy, InvalidTy, SpecificTy, ObjCPointerTy, CPointerTy, 216f4f0c6095d1f481b94c6821c65e3bf1c9df42af7Hans Wennborg AnyCharTy, CStrTy, WCStrTy, WIntTy }; 217826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenekprivate: 218826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek const Kind K; 219826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek QualType T; 220a792aff1c7de253b89c473fdb7eef4a5bba83aecHans Wennborg const char *Name; 22158e1e54476d610d6c33ef483f216ed8a1282d35cHans Wennborg bool Ptr; 222826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenekpublic: 22358e1e54476d610d6c33ef483f216ed8a1282d35cHans Wennborg ArgType(Kind k = UnknownTy, const char *n = 0) : K(k), Name(n), Ptr(false) {} 22458e1e54476d610d6c33ef483f216ed8a1282d35cHans Wennborg ArgType(QualType t, const char *n = 0) 22558e1e54476d610d6c33ef483f216ed8a1282d35cHans Wennborg : K(SpecificTy), T(t), Name(n), Ptr(false) {} 22658e1e54476d610d6c33ef483f216ed8a1282d35cHans Wennborg ArgType(CanQualType t) : K(SpecificTy), T(t), Name(0), Ptr(false) {} 227826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek 228f3749f4168c5cee59627a681ca4ca6e4116d0761Hans Wennborg static ArgType Invalid() { return ArgType(InvalidTy); } 229826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek bool isValid() const { return K != InvalidTy; } 230826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek 23158e1e54476d610d6c33ef483f216ed8a1282d35cHans Wennborg /// Create an ArgType which corresponds to the type pointer to A. 23258e1e54476d610d6c33ef483f216ed8a1282d35cHans Wennborg static ArgType PtrTo(const ArgType& A) { 23358e1e54476d610d6c33ef483f216ed8a1282d35cHans Wennborg assert(A.K >= InvalidTy && "ArgType cannot be pointer to invalid/unknown"); 23458e1e54476d610d6c33ef483f216ed8a1282d35cHans Wennborg ArgType Res = A; 23558e1e54476d610d6c33ef483f216ed8a1282d35cHans Wennborg Res.Ptr = true; 23658e1e54476d610d6c33ef483f216ed8a1282d35cHans Wennborg return Res; 23758e1e54476d610d6c33ef483f216ed8a1282d35cHans Wennborg } 23858e1e54476d610d6c33ef483f216ed8a1282d35cHans Wennborg 239826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek bool matchesType(ASTContext &C, QualType argTy) const; 240826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek 241826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek QualType getRepresentativeType(ASTContext &C) const; 242a792aff1c7de253b89c473fdb7eef4a5bba83aecHans Wennborg 243a792aff1c7de253b89c473fdb7eef4a5bba83aecHans Wennborg std::string getRepresentativeTypeName(ASTContext &C) const; 244826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek}; 245826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek 246826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenekclass OptionalAmount { 247826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenekpublic: 248826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek enum HowSpecified { NotSpecified, Constant, Arg, Invalid }; 249826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek 250826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek OptionalAmount(HowSpecified howSpecified, 251826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek unsigned amount, 252826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek const char *amountStart, 253826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek unsigned amountLength, 254826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek bool usesPositionalArg) 255826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek : start(amountStart), length(amountLength), hs(howSpecified), amt(amount), 256826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek UsesPositionalArg(usesPositionalArg), UsesDotPrefix(0) {} 257826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek 258826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek OptionalAmount(bool valid = true) 259826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek : start(0),length(0), hs(valid ? NotSpecified : Invalid), amt(0), 260826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek UsesPositionalArg(0), UsesDotPrefix(0) {} 261826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek 262826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek bool isInvalid() const { 263826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek return hs == Invalid; 264826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek } 265826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek 266826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek HowSpecified getHowSpecified() const { return hs; } 267826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek void setHowSpecified(HowSpecified h) { hs = h; } 268826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek 269826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek bool hasDataArgument() const { return hs == Arg; } 270826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek 271826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek unsigned getArgIndex() const { 272826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek assert(hasDataArgument()); 273826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek return amt; 274826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek } 275826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek 276826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek unsigned getConstantAmount() const { 277826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek assert(hs == Constant); 278826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek return amt; 279826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek } 280826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek 281826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek const char *getStart() const { 282826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek // We include the . character if it is given. 283826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek return start - UsesDotPrefix; 284826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek } 285826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek 286826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek unsigned getConstantLength() const { 287826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek assert(hs == Constant); 288826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek return length + UsesDotPrefix; 289826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek } 290826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek 291f3749f4168c5cee59627a681ca4ca6e4116d0761Hans Wennborg ArgType getArgType(ASTContext &Ctx) const; 292826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek 2938cc488fefb2fb04bc8d5398da29f0182f97934cfChris Lattner void toString(raw_ostream &os) const; 294826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek 295826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek bool usesPositionalArg() const { return (bool) UsesPositionalArg; } 296826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek unsigned getPositionalArgIndex() const { 297826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek assert(hasDataArgument()); 298826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek return amt + 1; 299826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek } 300826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek 301826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek bool usesDotPrefix() const { return UsesDotPrefix; } 302826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek void setUsesDotPrefix() { UsesDotPrefix = true; } 303826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek 304826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenekprivate: 305826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek const char *start; 306826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek unsigned length; 307826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek HowSpecified hs; 308826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek unsigned amt; 309826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek bool UsesPositionalArg : 1; 310826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek bool UsesDotPrefix; 311826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek}; 312826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek 313826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek 314826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenekclass FormatSpecifier { 315826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenekprotected: 316826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek LengthModifier LM; 317826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek OptionalAmount FieldWidth; 318a412a499162c46211c10ad92045b9b5fd2298edeTed Kremenek ConversionSpecifier CS; 319f85626453123f9691bcef13cff963f556e209c27Hans Wennborg /// Positional arguments, an IEEE extension: 320f85626453123f9691bcef13cff963f556e209c27Hans Wennborg /// IEEE Std 1003.1, 2004 Edition 321f85626453123f9691bcef13cff963f556e209c27Hans Wennborg /// http://www.opengroup.org/onlinepubs/009695399/functions/printf.html 322826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek bool UsesPositionalArg; 323826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek unsigned argIndex; 324826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenekpublic: 325a412a499162c46211c10ad92045b9b5fd2298edeTed Kremenek FormatSpecifier(bool isPrintf) 326a412a499162c46211c10ad92045b9b5fd2298edeTed Kremenek : CS(isPrintf), UsesPositionalArg(false), argIndex(0) {} 327826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek 328826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek void setLengthModifier(LengthModifier lm) { 329826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek LM = lm; 330826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek } 331826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek 332826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek void setUsesPositionalArg() { UsesPositionalArg = true; } 333826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek 334826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek void setArgIndex(unsigned i) { 335826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek argIndex = i; 336826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek } 337826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek 338826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek unsigned getArgIndex() const { 339826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek return argIndex; 340826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek } 341826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek 342826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek unsigned getPositionalArgIndex() const { 343826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek return argIndex + 1; 344826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek } 345826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek 346826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek const LengthModifier &getLengthModifier() const { 347826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek return LM; 348826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek } 349826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek 350826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek const OptionalAmount &getFieldWidth() const { 351826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek return FieldWidth; 352826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek } 353826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek 354826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek void setFieldWidth(const OptionalAmount &Amt) { 355826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek FieldWidth = Amt; 356826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek } 357826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek 358826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek bool usesPositionalArg() const { return UsesPositionalArg; } 359ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie 360bbb6bb4952b77e57b842b4d3096848123ae690e7Jordan Rose bool hasValidLengthModifier(const TargetInfo &Target) const; 36176517426dc8bf7734c07eefc35171a6bfdba1a2bHans Wennborg 36276517426dc8bf7734c07eefc35171a6bfdba1a2bHans Wennborg bool hasStandardLengthModifier() const; 36376517426dc8bf7734c07eefc35171a6bfdba1a2bHans Wennborg 364dc84cd5efdd3430efb22546b4ac656aa0540b210David Blaikie Optional<LengthModifier> getCorrectedLengthModifier() const; 365bbb6bb4952b77e57b842b4d3096848123ae690e7Jordan Rose 36676517426dc8bf7734c07eefc35171a6bfdba1a2bHans Wennborg bool hasStandardConversionSpecifier(const LangOptions &LangOpt) const; 36776517426dc8bf7734c07eefc35171a6bfdba1a2bHans Wennborg 36876517426dc8bf7734c07eefc35171a6bfdba1a2bHans Wennborg bool hasStandardLengthConversionCombination() const; 3694684778993c667246039b4664acbce59dc99440cHans Wennborg 3704684778993c667246039b4664acbce59dc99440cHans Wennborg /// For a TypedefType QT, if it is a named integer type such as size_t, 3714684778993c667246039b4664acbce59dc99440cHans Wennborg /// assign the appropriate value to LM and return true. 3724684778993c667246039b4664acbce59dc99440cHans Wennborg static bool namedTypeToLengthModifier(QualType QT, LengthModifier &LM); 373826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek}; 374826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek 375826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek} // end analyze_format_string namespace 376826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek 377826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek//===----------------------------------------------------------------------===// 378826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek/// Pieces specific to fprintf format strings. 379826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek 380826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremeneknamespace analyze_printf { 381826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek 382ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikieclass PrintfConversionSpecifier : 3836ecb950c65329f8d6ce9ad0514632df35a5ab61fTed Kremenek public analyze_format_string::ConversionSpecifier { 384826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenekpublic: 3856ecb950c65329f8d6ce9ad0514632df35a5ab61fTed Kremenek PrintfConversionSpecifier() 3866ecb950c65329f8d6ce9ad0514632df35a5ab61fTed Kremenek : ConversionSpecifier(true, 0, InvalidSpecifier) {} 3872da5036adaef57395270ef2dd82358fc513d8616Ted Kremenek 3886ecb950c65329f8d6ce9ad0514632df35a5ab61fTed Kremenek PrintfConversionSpecifier(const char *pos, Kind k) 3896ecb950c65329f8d6ce9ad0514632df35a5ab61fTed Kremenek : ConversionSpecifier(true, pos, k) {} 390826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek 391826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek bool isObjCArg() const { return kind >= ObjCBeg && kind <= ObjCEnd; } 392ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie bool isDoubleArg() const { return kind >= DoubleArgBeg && 3934ee01ef7bd170b6f3f3f71882b407cd6408c5b1eHans Wennborg kind <= DoubleArgEnd; } 394826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek unsigned getLength() const { 395826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek // Conversion specifiers currently only are represented by 396826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek // single characters, but we be flexible. 397826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek return 1; 398826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek } 399826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek 4006ecb950c65329f8d6ce9ad0514632df35a5ab61fTed Kremenek static bool classof(const analyze_format_string::ConversionSpecifier *CS) { 4016ecb950c65329f8d6ce9ad0514632df35a5ab61fTed Kremenek return CS->isPrintfKind(); 4026ecb950c65329f8d6ce9ad0514632df35a5ab61fTed Kremenek } 403826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek}; 404826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek 405f3749f4168c5cee59627a681ca4ca6e4116d0761Hans Wennborgusing analyze_format_string::ArgType; 406826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenekusing analyze_format_string::LengthModifier; 407826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenekusing analyze_format_string::OptionalAmount; 408826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenekusing analyze_format_string::OptionalFlag; 409826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek 410826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenekclass PrintfSpecifier : public analyze_format_string::FormatSpecifier { 411bd18d4584aae0ed6f7111ef5713784cf29fe663fTed Kremenek OptionalFlag HasThousandsGrouping; // ''', POSIX extension. 412826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek OptionalFlag IsLeftJustified; // '-' 413826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek OptionalFlag HasPlusPrefix; // '+' 414826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek OptionalFlag HasSpacePrefix; // ' ' 415826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek OptionalFlag HasAlternativeForm; // '#' 416826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek OptionalFlag HasLeadingZeroes; // '0' 417826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek OptionalAmount Precision; 418826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenekpublic: 419826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek PrintfSpecifier() : 420a412a499162c46211c10ad92045b9b5fd2298edeTed Kremenek FormatSpecifier(/* isPrintf = */ true), 421bd18d4584aae0ed6f7111ef5713784cf29fe663fTed Kremenek HasThousandsGrouping("'"), IsLeftJustified("-"), HasPlusPrefix("+"), 422bd18d4584aae0ed6f7111ef5713784cf29fe663fTed Kremenek HasSpacePrefix(" "), HasAlternativeForm("#"), HasLeadingZeroes("0") {} 423826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek 424826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek static PrintfSpecifier Parse(const char *beg, const char *end); 425826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek 426826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek // Methods for incrementally constructing the PrintfSpecifier. 4276ecb950c65329f8d6ce9ad0514632df35a5ab61fTed Kremenek void setConversionSpecifier(const PrintfConversionSpecifier &cs) { 428826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek CS = cs; 429826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek } 430bd18d4584aae0ed6f7111ef5713784cf29fe663fTed Kremenek void setHasThousandsGrouping(const char *position) { 431bd18d4584aae0ed6f7111ef5713784cf29fe663fTed Kremenek HasThousandsGrouping = true; 432bd18d4584aae0ed6f7111ef5713784cf29fe663fTed Kremenek HasThousandsGrouping.setPosition(position); 433bd18d4584aae0ed6f7111ef5713784cf29fe663fTed Kremenek } 434826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek void setIsLeftJustified(const char *position) { 435826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek IsLeftJustified = true; 436826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek IsLeftJustified.setPosition(position); 437826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek } 438826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek void setHasPlusPrefix(const char *position) { 439826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek HasPlusPrefix = true; 440826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek HasPlusPrefix.setPosition(position); 441826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek } 442826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek void setHasSpacePrefix(const char *position) { 443826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek HasSpacePrefix = true; 444826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek HasSpacePrefix.setPosition(position); 445826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek } 446826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek void setHasAlternativeForm(const char *position) { 447826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek HasAlternativeForm = true; 448826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek HasAlternativeForm.setPosition(position); 449826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek } 450826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek void setHasLeadingZeros(const char *position) { 451826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek HasLeadingZeroes = true; 452826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek HasLeadingZeroes.setPosition(position); 453826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek } 454826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek void setUsesPositionalArg() { UsesPositionalArg = true; } 455826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek 456826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek // Methods for querying the format specifier. 457826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek 4586ecb950c65329f8d6ce9ad0514632df35a5ab61fTed Kremenek const PrintfConversionSpecifier &getConversionSpecifier() const { 4596ecb950c65329f8d6ce9ad0514632df35a5ab61fTed Kremenek return cast<PrintfConversionSpecifier>(CS); 460826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek } 461826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek 462826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek void setPrecision(const OptionalAmount &Amt) { 463826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek Precision = Amt; 464826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek Precision.setUsesDotPrefix(); 465826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek } 466826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek 467826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek const OptionalAmount &getPrecision() const { 468826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek return Precision; 469826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek } 470ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie 471baa400654bd6f8396f9a07188445ae7955b060a3Ted Kremenek bool consumesDataArgument() const { 4726ecb950c65329f8d6ce9ad0514632df35a5ab61fTed Kremenek return getConversionSpecifier().consumesDataArgument(); 473baa400654bd6f8396f9a07188445ae7955b060a3Ted Kremenek } 474826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek 47596827eb52405a71c65c200949f3e644368e86454Michael J. Spencer /// \brief Returns the builtin type that a data argument 476baa400654bd6f8396f9a07188445ae7955b060a3Ted Kremenek /// paired with this format specifier should have. This method 47796827eb52405a71c65c200949f3e644368e86454Michael J. Spencer /// will return null if the format specifier does not have 478baa400654bd6f8396f9a07188445ae7955b060a3Ted Kremenek /// a matching data argument or the matching argument matches 479baa400654bd6f8396f9a07188445ae7955b060a3Ted Kremenek /// more than one type. 480f3749f4168c5cee59627a681ca4ca6e4116d0761Hans Wennborg ArgType getArgType(ASTContext &Ctx, bool IsObjCLiteral) const; 481826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek 482ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie const OptionalFlag &hasThousandsGrouping() const { 48365197b4b0c55bb74af0450230d61ee9461223721Ted Kremenek return HasThousandsGrouping; 48465197b4b0c55bb74af0450230d61ee9461223721Ted Kremenek } 485826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek const OptionalFlag &isLeftJustified() const { return IsLeftJustified; } 486826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek const OptionalFlag &hasPlusPrefix() const { return HasPlusPrefix; } 487826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek const OptionalFlag &hasAlternativeForm() const { return HasAlternativeForm; } 488826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek const OptionalFlag &hasLeadingZeros() const { return HasLeadingZeroes; } 489826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek const OptionalFlag &hasSpacePrefix() const { return HasSpacePrefix; } 490826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek bool usesPositionalArg() const { return UsesPositionalArg; } 491826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek 492be6126a2a784e1446460b8d15c2b26f880c871fcHans Wennborg /// Changes the specifier and length according to a QualType, retaining any 493be6126a2a784e1446460b8d15c2b26f880c871fcHans Wennborg /// flags or options. Returns true on success, or false when a conversion 494be6126a2a784e1446460b8d15c2b26f880c871fcHans Wennborg /// was not successful. 495be6126a2a784e1446460b8d15c2b26f880c871fcHans Wennborg bool fixType(QualType QT, const LangOptions &LangOpt, ASTContext &Ctx, 496be6126a2a784e1446460b8d15c2b26f880c871fcHans Wennborg bool IsObjCLiteral); 497826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek 4988cc488fefb2fb04bc8d5398da29f0182f97934cfChris Lattner void toString(raw_ostream &os) const; 499826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek 500ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie // Validation methods - to check if any element results in undefined behavior 501826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek bool hasValidPlusPrefix() const; 502826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek bool hasValidAlternativeForm() const; 503826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek bool hasValidLeadingZeros() const; 504826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek bool hasValidSpacePrefix() const; 505826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek bool hasValidLeftJustified() const; 50665197b4b0c55bb74af0450230d61ee9461223721Ted Kremenek bool hasValidThousandsGroupingPrefix() const; 507826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek 508826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek bool hasValidPrecision() const; 509826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek bool hasValidFieldWidth() const; 510826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek}; 511826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek} // end analyze_printf namespace 512826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek 513826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek//===----------------------------------------------------------------------===// 514826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek/// Pieces specific to fscanf format strings. 515826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek 516826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremeneknamespace analyze_scanf { 517826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek 518cfdcd3066521ee0fa9f303f3863c726943db37e5Ted Kremenekclass ScanfConversionSpecifier : 519cfdcd3066521ee0fa9f303f3863c726943db37e5Ted Kremenek public analyze_format_string::ConversionSpecifier { 520826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenekpublic: 5216ecb950c65329f8d6ce9ad0514632df35a5ab61fTed Kremenek ScanfConversionSpecifier() 522cfdcd3066521ee0fa9f303f3863c726943db37e5Ted Kremenek : ConversionSpecifier(false, 0, InvalidSpecifier) {} 523826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek 5246ecb950c65329f8d6ce9ad0514632df35a5ab61fTed Kremenek ScanfConversionSpecifier(const char *pos, Kind k) 525cfdcd3066521ee0fa9f303f3863c726943db37e5Ted Kremenek : ConversionSpecifier(false, pos, k) {} 526826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek 527826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek void setEndScanList(const char *pos) { EndScanList = pos; } 528ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie 529a412a499162c46211c10ad92045b9b5fd2298edeTed Kremenek static bool classof(const analyze_format_string::ConversionSpecifier *CS) { 530a412a499162c46211c10ad92045b9b5fd2298edeTed Kremenek return !CS->isPrintfKind(); 531ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie } 532826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek}; 533826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek 534f3749f4168c5cee59627a681ca4ca6e4116d0761Hans Wennborgusing analyze_format_string::ArgType; 535826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenekusing analyze_format_string::LengthModifier; 536826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenekusing analyze_format_string::OptionalAmount; 537826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenekusing analyze_format_string::OptionalFlag; 538826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek 539826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenekclass ScanfSpecifier : public analyze_format_string::FormatSpecifier { 540826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek OptionalFlag SuppressAssignment; // '*' 541826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenekpublic: 542a412a499162c46211c10ad92045b9b5fd2298edeTed Kremenek ScanfSpecifier() : 543a412a499162c46211c10ad92045b9b5fd2298edeTed Kremenek FormatSpecifier(/* isPrintf = */ false), 544a412a499162c46211c10ad92045b9b5fd2298edeTed Kremenek SuppressAssignment("*") {} 545826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek 546826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek void setSuppressAssignment(const char *position) { 547826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek SuppressAssignment = true; 548826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek SuppressAssignment.setPosition(position); 549826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek } 550826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek 551826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek const OptionalFlag &getSuppressAssignment() const { 552826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek return SuppressAssignment; 553826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek } 554826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek 5556ecb950c65329f8d6ce9ad0514632df35a5ab61fTed Kremenek void setConversionSpecifier(const ScanfConversionSpecifier &cs) { 556826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek CS = cs; 557826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek } 558826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek 5596ecb950c65329f8d6ce9ad0514632df35a5ab61fTed Kremenek const ScanfConversionSpecifier &getConversionSpecifier() const { 560a412a499162c46211c10ad92045b9b5fd2298edeTed Kremenek return cast<ScanfConversionSpecifier>(CS); 561826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek } 562ba243b59a1074e0962f6abfa3bb9aa984eac1245David Blaikie 563826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek bool consumesDataArgument() const { 564826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek return CS.consumesDataArgument() && !SuppressAssignment; 565826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek } 566826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek 56758e1e54476d610d6c33ef483f216ed8a1282d35cHans Wennborg ArgType getArgType(ASTContext &Ctx) const; 5686fcd932dfd6835f70cc00d6f7c6789793f6d7b66Hans Wennborg 569be6126a2a784e1446460b8d15c2b26f880c871fcHans Wennborg bool fixType(QualType QT, const LangOptions &LangOpt, ASTContext &Ctx); 5706fcd932dfd6835f70cc00d6f7c6789793f6d7b66Hans Wennborg 5716fcd932dfd6835f70cc00d6f7c6789793f6d7b66Hans Wennborg void toString(raw_ostream &os) const; 5726fcd932dfd6835f70cc00d6f7c6789793f6d7b66Hans Wennborg 573826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek static ScanfSpecifier Parse(const char *beg, const char *end); 574826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek}; 575826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek 576826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek} // end analyze_scanf namespace 577826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek 578826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek//===----------------------------------------------------------------------===// 579826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek// Parsing and processing of format strings (both fprintf and fscanf). 580826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek 581826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremeneknamespace analyze_format_string { 582826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek 583826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenekenum PositionContext { FieldWidthPos = 0, PrecisionPos = 1 }; 584826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek 585826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenekclass FormatStringHandler { 586826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenekpublic: 587826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek FormatStringHandler() {} 588826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek virtual ~FormatStringHandler(); 589826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek 590826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek virtual void HandleNullChar(const char *nullCharacter) {} 591826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek 592f85626453123f9691bcef13cff963f556e209c27Hans Wennborg virtual void HandlePosition(const char *startPos, unsigned posLen) {} 593f85626453123f9691bcef13cff963f556e209c27Hans Wennborg 594826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek virtual void HandleInvalidPosition(const char *startPos, unsigned posLen, 595826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek PositionContext p) {} 596826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek 597826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek virtual void HandleZeroPosition(const char *startPos, unsigned posLen) {} 598826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek 599826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek virtual void HandleIncompleteSpecifier(const char *startSpecifier, 600826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek unsigned specifierLen) {} 601826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek 602826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek // Printf-specific handlers. 603826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek 604826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek virtual bool HandleInvalidPrintfConversionSpecifier( 605826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek const analyze_printf::PrintfSpecifier &FS, 606826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek const char *startSpecifier, 607826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek unsigned specifierLen) { 608826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek return true; 609826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek } 610826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek 611826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek virtual bool HandlePrintfSpecifier(const analyze_printf::PrintfSpecifier &FS, 612826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek const char *startSpecifier, 613826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek unsigned specifierLen) { 614826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek return true; 615826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek } 616826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek 617826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek // Scanf-specific handlers. 618826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek 619826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek virtual bool HandleInvalidScanfConversionSpecifier( 620826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek const analyze_scanf::ScanfSpecifier &FS, 621826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek const char *startSpecifier, 622826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek unsigned specifierLen) { 623826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek return true; 624826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek } 625826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek 626826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek virtual bool HandleScanfSpecifier(const analyze_scanf::ScanfSpecifier &FS, 627826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek const char *startSpecifier, 628826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek unsigned specifierLen) { 629826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek return true; 630826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek } 631826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek 632826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek virtual void HandleIncompleteScanList(const char *start, const char *end) {} 633826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek}; 634826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek 635826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenekbool ParsePrintfString(FormatStringHandler &H, 636275b6f52c7bcafc1f3cf291813b5c60ee776965aJordan Rose const char *beg, const char *end, const LangOptions &LO, 637275b6f52c7bcafc1f3cf291813b5c60ee776965aJordan Rose const TargetInfo &Target); 638826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek 639826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenekbool ParseScanfString(FormatStringHandler &H, 640275b6f52c7bcafc1f3cf291813b5c60ee776965aJordan Rose const char *beg, const char *end, const LangOptions &LO, 641275b6f52c7bcafc1f3cf291813b5c60ee776965aJordan Rose const TargetInfo &Target); 642826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek 643826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek} // end analyze_format_string namespace 644826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek} // end clang namespace 645826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek#endif 646