PrintfFormatString.cpp revision a792aff1c7de253b89c473fdb7eef4a5bba83aec
1826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek//== PrintfFormatString.cpp - Analysis of printf format strings --*- C++ -*-==// 28f0a1c73fd2b83afd4b1fce6f964535b51d13659Ted Kremenek// 38f0a1c73fd2b83afd4b1fce6f964535b51d13659Ted Kremenek// The LLVM Compiler Infrastructure 48f0a1c73fd2b83afd4b1fce6f964535b51d13659Ted Kremenek// 58f0a1c73fd2b83afd4b1fce6f964535b51d13659Ted Kremenek// This file is distributed under the University of Illinois Open Source 68f0a1c73fd2b83afd4b1fce6f964535b51d13659Ted Kremenek// License. See LICENSE.TXT for details. 78f0a1c73fd2b83afd4b1fce6f964535b51d13659Ted Kremenek// 88f0a1c73fd2b83afd4b1fce6f964535b51d13659Ted Kremenek//===----------------------------------------------------------------------===// 98f0a1c73fd2b83afd4b1fce6f964535b51d13659Ted Kremenek// 108f0a1c73fd2b83afd4b1fce6f964535b51d13659Ted Kremenek// Handling of format string in printf and friends. The structure of format 118f0a1c73fd2b83afd4b1fce6f964535b51d13659Ted Kremenek// strings for fprintf() are described in C99 7.19.6.1. 128f0a1c73fd2b83afd4b1fce6f964535b51d13659Ted Kremenek// 138f0a1c73fd2b83afd4b1fce6f964535b51d13659Ted Kremenek//===----------------------------------------------------------------------===// 148f0a1c73fd2b83afd4b1fce6f964535b51d13659Ted Kremenek 15826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek#include "clang/Analysis/Analyses/FormatString.h" 16826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek#include "FormatStringParsing.h" 178f0a1c73fd2b83afd4b1fce6f964535b51d13659Ted Kremenek 18826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenekusing clang::analyze_format_string::ArgTypeResult; 19826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenekusing clang::analyze_format_string::FormatStringHandler; 20826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenekusing clang::analyze_format_string::LengthModifier; 21826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenekusing clang::analyze_format_string::OptionalAmount; 226ecb950c65329f8d6ce9ad0514632df35a5ab61fTed Kremenekusing clang::analyze_format_string::ConversionSpecifier; 23826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenekusing clang::analyze_printf::PrintfSpecifier; 24efaff195ba1fa55b6fe0b0b2435b81451387d241Ted Kremenek 25808015a18bd97781ce437831a95a92fdfc8d5136Ted Kremenekusing namespace clang; 268f0a1c73fd2b83afd4b1fce6f964535b51d13659Ted Kremenek 27826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenektypedef clang::analyze_format_string::SpecifierResult<PrintfSpecifier> 28826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek PrintfSpecifierResult; 294e4b30ec62d78b24e6556fea2624855c193d0e3eTed Kremenek 304e4b30ec62d78b24e6556fea2624855c193d0e3eTed Kremenek//===----------------------------------------------------------------------===// 314e4b30ec62d78b24e6556fea2624855c193d0e3eTed Kremenek// Methods for parsing format strings. 324e4b30ec62d78b24e6556fea2624855c193d0e3eTed Kremenek//===----------------------------------------------------------------------===// 338f0a1c73fd2b83afd4b1fce6f964535b51d13659Ted Kremenek 34826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenekusing analyze_format_string::ParseNonPositionAmount; 35efaff195ba1fa55b6fe0b0b2435b81451387d241Ted Kremenek 36826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenekstatic bool ParsePrecision(FormatStringHandler &H, PrintfSpecifier &FS, 37efaff195ba1fa55b6fe0b0b2435b81451387d241Ted Kremenek const char *Start, const char *&Beg, const char *E, 38efaff195ba1fa55b6fe0b0b2435b81451387d241Ted Kremenek unsigned *argIndex) { 39efaff195ba1fa55b6fe0b0b2435b81451387d241Ted Kremenek if (argIndex) { 40efaff195ba1fa55b6fe0b0b2435b81451387d241Ted Kremenek FS.setPrecision(ParseNonPositionAmount(Beg, E, *argIndex)); 413060178ad9df29789505c1e6debcfc80a3a13587Chad Rosier } else { 42efaff195ba1fa55b6fe0b0b2435b81451387d241Ted Kremenek const OptionalAmount Amt = ParsePositionAmount(H, Start, Beg, E, 43826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek analyze_format_string::PrecisionPos); 44efaff195ba1fa55b6fe0b0b2435b81451387d241Ted Kremenek if (Amt.isInvalid()) 45efaff195ba1fa55b6fe0b0b2435b81451387d241Ted Kremenek return true; 46efaff195ba1fa55b6fe0b0b2435b81451387d241Ted Kremenek FS.setPrecision(Amt); 47efaff195ba1fa55b6fe0b0b2435b81451387d241Ted Kremenek } 48efaff195ba1fa55b6fe0b0b2435b81451387d241Ted Kremenek return false; 49efaff195ba1fa55b6fe0b0b2435b81451387d241Ted Kremenek} 50efaff195ba1fa55b6fe0b0b2435b81451387d241Ted Kremenek 51826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenekstatic PrintfSpecifierResult ParsePrintfSpecifier(FormatStringHandler &H, 5274d56a168966ff015824279a24aaf566180ed97dTed Kremenek const char *&Beg, 537f70dc85d5055c19c8003f43a59135de211ad1b9Ted Kremenek const char *E, 547f70dc85d5055c19c8003f43a59135de211ad1b9Ted Kremenek unsigned &argIndex) { 554e4b30ec62d78b24e6556fea2624855c193d0e3eTed Kremenek 566ecb950c65329f8d6ce9ad0514632df35a5ab61fTed Kremenek using namespace clang::analyze_format_string; 574b220fae2f525fda39685ddfa7759950db1185e2Ted Kremenek using namespace clang::analyze_printf; 584e4b30ec62d78b24e6556fea2624855c193d0e3eTed Kremenek 598f0a1c73fd2b83afd4b1fce6f964535b51d13659Ted Kremenek const char *I = Beg; 60c7ae51a3cd9460db8280e8623c90614f246e46d2Ted Kremenek const char *Start = 0; 618f0a1c73fd2b83afd4b1fce6f964535b51d13659Ted Kremenek UpdateOnReturn <const char*> UpdateBeg(Beg, I); 628f0a1c73fd2b83afd4b1fce6f964535b51d13659Ted Kremenek 638f0a1c73fd2b83afd4b1fce6f964535b51d13659Ted Kremenek // Look for a '%' character that indicates the start of a format specifier. 64e729acbba75903f42e79e72e46cdebe3f4c35521Ted Kremenek for ( ; I != E ; ++I) { 658f0a1c73fd2b83afd4b1fce6f964535b51d13659Ted Kremenek char c = *I; 668f0a1c73fd2b83afd4b1fce6f964535b51d13659Ted Kremenek if (c == '\0') { 678f0a1c73fd2b83afd4b1fce6f964535b51d13659Ted Kremenek // Detect spurious null characters, which are likely errors. 688f0a1c73fd2b83afd4b1fce6f964535b51d13659Ted Kremenek H.HandleNullChar(I); 698f0a1c73fd2b83afd4b1fce6f964535b51d13659Ted Kremenek return true; 708f0a1c73fd2b83afd4b1fce6f964535b51d13659Ted Kremenek } 718f0a1c73fd2b83afd4b1fce6f964535b51d13659Ted Kremenek if (c == '%') { 72e729acbba75903f42e79e72e46cdebe3f4c35521Ted Kremenek Start = I++; // Record the start of the format specifier. 738f0a1c73fd2b83afd4b1fce6f964535b51d13659Ted Kremenek break; 748f0a1c73fd2b83afd4b1fce6f964535b51d13659Ted Kremenek } 758f0a1c73fd2b83afd4b1fce6f964535b51d13659Ted Kremenek } 764e4b30ec62d78b24e6556fea2624855c193d0e3eTed Kremenek 778f0a1c73fd2b83afd4b1fce6f964535b51d13659Ted Kremenek // No format specifier found? 788f0a1c73fd2b83afd4b1fce6f964535b51d13659Ted Kremenek if (!Start) 798f0a1c73fd2b83afd4b1fce6f964535b51d13659Ted Kremenek return false; 804e4b30ec62d78b24e6556fea2624855c193d0e3eTed Kremenek 818f0a1c73fd2b83afd4b1fce6f964535b51d13659Ted Kremenek if (I == E) { 828f0a1c73fd2b83afd4b1fce6f964535b51d13659Ted Kremenek // No more characters left? 83826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek H.HandleIncompleteSpecifier(Start, E - Start); 848f0a1c73fd2b83afd4b1fce6f964535b51d13659Ted Kremenek return true; 858f0a1c73fd2b83afd4b1fce6f964535b51d13659Ted Kremenek } 864e4b30ec62d78b24e6556fea2624855c193d0e3eTed Kremenek 87826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek PrintfSpecifier FS; 88efaff195ba1fa55b6fe0b0b2435b81451387d241Ted Kremenek if (ParseArgPosition(H, FS, Start, I, E)) 89efaff195ba1fa55b6fe0b0b2435b81451387d241Ted Kremenek return true; 90efaff195ba1fa55b6fe0b0b2435b81451387d241Ted Kremenek 91efaff195ba1fa55b6fe0b0b2435b81451387d241Ted Kremenek if (I == E) { 92efaff195ba1fa55b6fe0b0b2435b81451387d241Ted Kremenek // No more characters left? 93826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek H.HandleIncompleteSpecifier(Start, E - Start); 94efaff195ba1fa55b6fe0b0b2435b81451387d241Ted Kremenek return true; 95efaff195ba1fa55b6fe0b0b2435b81451387d241Ted Kremenek } 964e4b30ec62d78b24e6556fea2624855c193d0e3eTed Kremenek 978f0a1c73fd2b83afd4b1fce6f964535b51d13659Ted Kremenek // Look for flags (if any). 988f0a1c73fd2b83afd4b1fce6f964535b51d13659Ted Kremenek bool hasMore = true; 998f0a1c73fd2b83afd4b1fce6f964535b51d13659Ted Kremenek for ( ; I != E; ++I) { 1008f0a1c73fd2b83afd4b1fce6f964535b51d13659Ted Kremenek switch (*I) { 1018f0a1c73fd2b83afd4b1fce6f964535b51d13659Ted Kremenek default: hasMore = false; break; 102dfbb02a16ac8c764b5ba1742450513d6212d2f9fNAKAMURA Takumi case '\'': 103bd18d4584aae0ed6f7111ef5713784cf29fe663fTed Kremenek // FIXME: POSIX specific. Always accept? 104bd18d4584aae0ed6f7111ef5713784cf29fe663fTed Kremenek FS.setHasThousandsGrouping(I); 105bd18d4584aae0ed6f7111ef5713784cf29fe663fTed Kremenek break; 106e4ee9663168dfb2b4122c768091e30217328c9faTom Care case '-': FS.setIsLeftJustified(I); break; 107e4ee9663168dfb2b4122c768091e30217328c9faTom Care case '+': FS.setHasPlusPrefix(I); break; 108e4ee9663168dfb2b4122c768091e30217328c9faTom Care case ' ': FS.setHasSpacePrefix(I); break; 109e4ee9663168dfb2b4122c768091e30217328c9faTom Care case '#': FS.setHasAlternativeForm(I); break; 110e4ee9663168dfb2b4122c768091e30217328c9faTom Care case '0': FS.setHasLeadingZeros(I); break; 1118f0a1c73fd2b83afd4b1fce6f964535b51d13659Ted Kremenek } 1128f0a1c73fd2b83afd4b1fce6f964535b51d13659Ted Kremenek if (!hasMore) 1138f0a1c73fd2b83afd4b1fce6f964535b51d13659Ted Kremenek break; 1144e4b30ec62d78b24e6556fea2624855c193d0e3eTed Kremenek } 1158f0a1c73fd2b83afd4b1fce6f964535b51d13659Ted Kremenek 1168f0a1c73fd2b83afd4b1fce6f964535b51d13659Ted Kremenek if (I == E) { 1178f0a1c73fd2b83afd4b1fce6f964535b51d13659Ted Kremenek // No more characters left? 118826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek H.HandleIncompleteSpecifier(Start, E - Start); 1198f0a1c73fd2b83afd4b1fce6f964535b51d13659Ted Kremenek return true; 1208f0a1c73fd2b83afd4b1fce6f964535b51d13659Ted Kremenek } 1214e4b30ec62d78b24e6556fea2624855c193d0e3eTed Kremenek 1228f0a1c73fd2b83afd4b1fce6f964535b51d13659Ted Kremenek // Look for the field width (if any). 123efaff195ba1fa55b6fe0b0b2435b81451387d241Ted Kremenek if (ParseFieldWidth(H, FS, Start, I, E, 124efaff195ba1fa55b6fe0b0b2435b81451387d241Ted Kremenek FS.usesPositionalArg() ? 0 : &argIndex)) 125efaff195ba1fa55b6fe0b0b2435b81451387d241Ted Kremenek return true; 1264e4b30ec62d78b24e6556fea2624855c193d0e3eTed Kremenek 1278f0a1c73fd2b83afd4b1fce6f964535b51d13659Ted Kremenek if (I == E) { 1288f0a1c73fd2b83afd4b1fce6f964535b51d13659Ted Kremenek // No more characters left? 129826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek H.HandleIncompleteSpecifier(Start, E - Start); 1308f0a1c73fd2b83afd4b1fce6f964535b51d13659Ted Kremenek return true; 1314e4b30ec62d78b24e6556fea2624855c193d0e3eTed Kremenek } 1324e4b30ec62d78b24e6556fea2624855c193d0e3eTed Kremenek 1334e4b30ec62d78b24e6556fea2624855c193d0e3eTed Kremenek // Look for the precision (if any). 1348f0a1c73fd2b83afd4b1fce6f964535b51d13659Ted Kremenek if (*I == '.') { 135808015a18bd97781ce437831a95a92fdfc8d5136Ted Kremenek ++I; 1368f0a1c73fd2b83afd4b1fce6f964535b51d13659Ted Kremenek if (I == E) { 137826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek H.HandleIncompleteSpecifier(Start, E - Start); 1388f0a1c73fd2b83afd4b1fce6f964535b51d13659Ted Kremenek return true; 1398f0a1c73fd2b83afd4b1fce6f964535b51d13659Ted Kremenek } 1404e4b30ec62d78b24e6556fea2624855c193d0e3eTed Kremenek 141efaff195ba1fa55b6fe0b0b2435b81451387d241Ted Kremenek if (ParsePrecision(H, FS, Start, I, E, 142efaff195ba1fa55b6fe0b0b2435b81451387d241Ted Kremenek FS.usesPositionalArg() ? 0 : &argIndex)) 143efaff195ba1fa55b6fe0b0b2435b81451387d241Ted Kremenek return true; 1448f0a1c73fd2b83afd4b1fce6f964535b51d13659Ted Kremenek 1458f0a1c73fd2b83afd4b1fce6f964535b51d13659Ted Kremenek if (I == E) { 1468f0a1c73fd2b83afd4b1fce6f964535b51d13659Ted Kremenek // No more characters left? 147826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek H.HandleIncompleteSpecifier(Start, E - Start); 1488f0a1c73fd2b83afd4b1fce6f964535b51d13659Ted Kremenek return true; 1498f0a1c73fd2b83afd4b1fce6f964535b51d13659Ted Kremenek } 1508f0a1c73fd2b83afd4b1fce6f964535b51d13659Ted Kremenek } 1518f0a1c73fd2b83afd4b1fce6f964535b51d13659Ted Kremenek 1528f0a1c73fd2b83afd4b1fce6f964535b51d13659Ted Kremenek // Look for the length modifier. 153826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek if (ParseLengthModifier(FS, I, E) && I == E) { 1548f0a1c73fd2b83afd4b1fce6f964535b51d13659Ted Kremenek // No more characters left? 155826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek H.HandleIncompleteSpecifier(Start, E - Start); 1568f0a1c73fd2b83afd4b1fce6f964535b51d13659Ted Kremenek return true; 1578f0a1c73fd2b83afd4b1fce6f964535b51d13659Ted Kremenek } 158df17f9d95ba03ba41d8d39ccb688a4eb2ee00e9aTed Kremenek 1594dcb18ff9d92c66c78077ac5cae4b83af37292e4Ted Kremenek if (*I == '\0') { 160df17f9d95ba03ba41d8d39ccb688a4eb2ee00e9aTed Kremenek // Detect spurious null characters, which are likely errors. 161df17f9d95ba03ba41d8d39ccb688a4eb2ee00e9aTed Kremenek H.HandleNullChar(I); 162df17f9d95ba03ba41d8d39ccb688a4eb2ee00e9aTed Kremenek return true; 1634dcb18ff9d92c66c78077ac5cae4b83af37292e4Ted Kremenek } 1644e4b30ec62d78b24e6556fea2624855c193d0e3eTed Kremenek 1658f0a1c73fd2b83afd4b1fce6f964535b51d13659Ted Kremenek // Finally, look for the conversion specifier. 166a8d8fec7876666d90bb2a144d3b832b2d89a088aTed Kremenek const char *conversionPosition = I++; 16726ac2e07b46bfb4d4f00752c96481c0a98c79c69Ted Kremenek ConversionSpecifier::Kind k = ConversionSpecifier::InvalidSpecifier; 168a8d8fec7876666d90bb2a144d3b832b2d89a088aTed Kremenek switch (*conversionPosition) { 1698f0a1c73fd2b83afd4b1fce6f964535b51d13659Ted Kremenek default: 17026ac2e07b46bfb4d4f00752c96481c0a98c79c69Ted Kremenek break; 171c7cbb9bf8e0bf8c3191ef0b782ec198c433d2a4eTed Kremenek // C99: 7.19.6.1 (section 8). 17287260c7eabf88eb2009ba2ba20150cd897483241Ted Kremenek case '%': k = ConversionSpecifier::PercentArg; break; 17387260c7eabf88eb2009ba2ba20150cd897483241Ted Kremenek case 'A': k = ConversionSpecifier::AArg; break; 174a8d8fec7876666d90bb2a144d3b832b2d89a088aTed Kremenek case 'E': k = ConversionSpecifier::EArg; break; 17587260c7eabf88eb2009ba2ba20150cd897483241Ted Kremenek case 'F': k = ConversionSpecifier::FArg; break; 176a8d8fec7876666d90bb2a144d3b832b2d89a088aTed Kremenek case 'G': k = ConversionSpecifier::GArg; break; 17787260c7eabf88eb2009ba2ba20150cd897483241Ted Kremenek case 'X': k = ConversionSpecifier::XArg; break; 178a8d8fec7876666d90bb2a144d3b832b2d89a088aTed Kremenek case 'a': k = ConversionSpecifier::aArg; break; 17992a6febe130dd9ad726983835297e11b2fa3b93fTed Kremenek case 'c': k = ConversionSpecifier::cArg; break; 18087260c7eabf88eb2009ba2ba20150cd897483241Ted Kremenek case 'd': k = ConversionSpecifier::dArg; break; 18187260c7eabf88eb2009ba2ba20150cd897483241Ted Kremenek case 'e': k = ConversionSpecifier::eArg; break; 18287260c7eabf88eb2009ba2ba20150cd897483241Ted Kremenek case 'f': k = ConversionSpecifier::fArg; break; 18387260c7eabf88eb2009ba2ba20150cd897483241Ted Kremenek case 'g': k = ConversionSpecifier::gArg; break; 18487260c7eabf88eb2009ba2ba20150cd897483241Ted Kremenek case 'i': k = ConversionSpecifier::iArg; break; 18535d353b47bce29200b910371dd9b8ba7f3058ab8Ted Kremenek case 'n': k = ConversionSpecifier::nArg; break; 18687260c7eabf88eb2009ba2ba20150cd897483241Ted Kremenek case 'o': k = ConversionSpecifier::oArg; break; 18766932056da99d2441e27c10b27c82706671e1dbfTed Kremenek case 'p': k = ConversionSpecifier::pArg; break; 18899196b1031d37d37f395a3291ccdd12a3fc01242Ted Kremenek case 's': k = ConversionSpecifier::sArg; break; 18987260c7eabf88eb2009ba2ba20150cd897483241Ted Kremenek case 'u': k = ConversionSpecifier::uArg; break; 19087260c7eabf88eb2009ba2ba20150cd897483241Ted Kremenek case 'x': k = ConversionSpecifier::xArg; break; 191bd18d4584aae0ed6f7111ef5713784cf29fe663fTed Kremenek // POSIX specific. 19287260c7eabf88eb2009ba2ba20150cd897483241Ted Kremenek case 'C': k = ConversionSpecifier::CArg; break; 193de183a48dd8fcff5e0343e84c8a6b563088447ceTed Kremenek case 'S': k = ConversionSpecifier::SArg; break; 194c7cbb9bf8e0bf8c3191ef0b782ec198c433d2a4eTed Kremenek // Objective-C. 1954dcb18ff9d92c66c78077ac5cae4b83af37292e4Ted Kremenek case '@': k = ConversionSpecifier::ObjCObjArg; break; 196df17f9d95ba03ba41d8d39ccb688a4eb2ee00e9aTed Kremenek // Glibc specific. 1974dcb18ff9d92c66c78077ac5cae4b83af37292e4Ted Kremenek case 'm': k = ConversionSpecifier::PrintErrno; break; 1988f0a1c73fd2b83afd4b1fce6f964535b51d13659Ted Kremenek } 1996ecb950c65329f8d6ce9ad0514632df35a5ab61fTed Kremenek PrintfConversionSpecifier CS(conversionPosition, k); 2007f70dc85d5055c19c8003f43a59135de211ad1b9Ted Kremenek FS.setConversionSpecifier(CS); 201efaff195ba1fa55b6fe0b0b2435b81451387d241Ted Kremenek if (CS.consumesDataArgument() && !FS.usesPositionalArg()) 2027f70dc85d5055c19c8003f43a59135de211ad1b9Ted Kremenek FS.setArgIndex(argIndex++); 20326ac2e07b46bfb4d4f00752c96481c0a98c79c69Ted Kremenek 20426ac2e07b46bfb4d4f00752c96481c0a98c79c69Ted Kremenek if (k == ConversionSpecifier::InvalidSpecifier) { 2057f70dc85d5055c19c8003f43a59135de211ad1b9Ted Kremenek // Assume the conversion takes one argument. 2067966297a70996977f167a8676568f02f4283bdd6Ted Kremenek return !H.HandleInvalidPrintfConversionSpecifier(FS, Start, I - Start); 20726ac2e07b46bfb4d4f00752c96481c0a98c79c69Ted Kremenek } 208826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek return PrintfSpecifierResult(Start, FS); 2098f0a1c73fd2b83afd4b1fce6f964535b51d13659Ted Kremenek} 2108f0a1c73fd2b83afd4b1fce6f964535b51d13659Ted Kremenek 211826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenekbool clang::analyze_format_string::ParsePrintfString(FormatStringHandler &H, 212826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek const char *I, 213826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek const char *E) { 2147f70dc85d5055c19c8003f43a59135de211ad1b9Ted Kremenek 2157f70dc85d5055c19c8003f43a59135de211ad1b9Ted Kremenek unsigned argIndex = 0; 2167f70dc85d5055c19c8003f43a59135de211ad1b9Ted Kremenek 2178f0a1c73fd2b83afd4b1fce6f964535b51d13659Ted Kremenek // Keep looking for a format specifier until we have exhausted the string. 2188f0a1c73fd2b83afd4b1fce6f964535b51d13659Ted Kremenek while (I != E) { 219826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek const PrintfSpecifierResult &FSR = ParsePrintfSpecifier(H, I, E, argIndex); 22026ac2e07b46bfb4d4f00752c96481c0a98c79c69Ted Kremenek // Did a fail-stop error of any kind occur when parsing the specifier? 22126ac2e07b46bfb4d4f00752c96481c0a98c79c69Ted Kremenek // If so, don't do any more processing. 22226ac2e07b46bfb4d4f00752c96481c0a98c79c69Ted Kremenek if (FSR.shouldStop()) 2238f0a1c73fd2b83afd4b1fce6f964535b51d13659Ted Kremenek return true;; 22426ac2e07b46bfb4d4f00752c96481c0a98c79c69Ted Kremenek // Did we exhaust the string or encounter an error that 22526ac2e07b46bfb4d4f00752c96481c0a98c79c69Ted Kremenek // we can recover from? 2268f0a1c73fd2b83afd4b1fce6f964535b51d13659Ted Kremenek if (!FSR.hasValue()) 22726ac2e07b46bfb4d4f00752c96481c0a98c79c69Ted Kremenek continue; 2288f0a1c73fd2b83afd4b1fce6f964535b51d13659Ted Kremenek // We have a format specifier. Pass it to the callback. 229826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek if (!H.HandlePrintfSpecifier(FSR.getValue(), FSR.getStart(), 230a8d8fec7876666d90bb2a144d3b832b2d89a088aTed Kremenek I - FSR.getStart())) 2314dcb18ff9d92c66c78077ac5cae4b83af37292e4Ted Kremenek return true; 2324e4b30ec62d78b24e6556fea2624855c193d0e3eTed Kremenek } 2334e4b30ec62d78b24e6556fea2624855c193d0e3eTed Kremenek assert(I == E && "Format string not exhausted"); 2348f0a1c73fd2b83afd4b1fce6f964535b51d13659Ted Kremenek return false; 2358f0a1c73fd2b83afd4b1fce6f964535b51d13659Ted Kremenek} 2368f0a1c73fd2b83afd4b1fce6f964535b51d13659Ted Kremenek 2374e4b30ec62d78b24e6556fea2624855c193d0e3eTed Kremenek//===----------------------------------------------------------------------===// 2383bfc5f49e0e37e235bb0d33bcbcb36af9d1f84abTom Care// Methods on ConversionSpecifier. 2393bfc5f49e0e37e235bb0d33bcbcb36af9d1f84abTom Care//===----------------------------------------------------------------------===// 2403bfc5f49e0e37e235bb0d33bcbcb36af9d1f84abTom Careconst char *ConversionSpecifier::toString() const { 2413bfc5f49e0e37e235bb0d33bcbcb36af9d1f84abTom Care switch (kind) { 2423bfc5f49e0e37e235bb0d33bcbcb36af9d1f84abTom Care case dArg: return "d"; 2433bfc5f49e0e37e235bb0d33bcbcb36af9d1f84abTom Care case iArg: return "i"; 2443bfc5f49e0e37e235bb0d33bcbcb36af9d1f84abTom Care case oArg: return "o"; 2453bfc5f49e0e37e235bb0d33bcbcb36af9d1f84abTom Care case uArg: return "u"; 2463bfc5f49e0e37e235bb0d33bcbcb36af9d1f84abTom Care case xArg: return "x"; 2473bfc5f49e0e37e235bb0d33bcbcb36af9d1f84abTom Care case XArg: return "X"; 2483bfc5f49e0e37e235bb0d33bcbcb36af9d1f84abTom Care case fArg: return "f"; 2493bfc5f49e0e37e235bb0d33bcbcb36af9d1f84abTom Care case FArg: return "F"; 2503bfc5f49e0e37e235bb0d33bcbcb36af9d1f84abTom Care case eArg: return "e"; 2513bfc5f49e0e37e235bb0d33bcbcb36af9d1f84abTom Care case EArg: return "E"; 2523bfc5f49e0e37e235bb0d33bcbcb36af9d1f84abTom Care case gArg: return "g"; 2533bfc5f49e0e37e235bb0d33bcbcb36af9d1f84abTom Care case GArg: return "G"; 2543bfc5f49e0e37e235bb0d33bcbcb36af9d1f84abTom Care case aArg: return "a"; 2553bfc5f49e0e37e235bb0d33bcbcb36af9d1f84abTom Care case AArg: return "A"; 2567fdba13847f01cfcdc7c9261b13e99e3cbecb5fcTed Kremenek case cArg: return "c"; 2577fdba13847f01cfcdc7c9261b13e99e3cbecb5fcTed Kremenek case sArg: return "s"; 2587fdba13847f01cfcdc7c9261b13e99e3cbecb5fcTed Kremenek case pArg: return "p"; 2597fdba13847f01cfcdc7c9261b13e99e3cbecb5fcTed Kremenek case nArg: return "n"; 2607fdba13847f01cfcdc7c9261b13e99e3cbecb5fcTed Kremenek case PercentArg: return "%"; 2617fdba13847f01cfcdc7c9261b13e99e3cbecb5fcTed Kremenek case ScanListArg: return "["; 2623bfc5f49e0e37e235bb0d33bcbcb36af9d1f84abTom Care case InvalidSpecifier: return NULL; 2633bfc5f49e0e37e235bb0d33bcbcb36af9d1f84abTom Care 2643bfc5f49e0e37e235bb0d33bcbcb36af9d1f84abTom Care // MacOS X unicode extensions. 2657fdba13847f01cfcdc7c9261b13e99e3cbecb5fcTed Kremenek case CArg: return "C"; 266de183a48dd8fcff5e0343e84c8a6b563088447ceTed Kremenek case SArg: return "S"; 2673bfc5f49e0e37e235bb0d33bcbcb36af9d1f84abTom Care 2683bfc5f49e0e37e235bb0d33bcbcb36af9d1f84abTom Care // Objective-C specific specifiers. 2693bfc5f49e0e37e235bb0d33bcbcb36af9d1f84abTom Care case ObjCObjArg: return "@"; 2703bfc5f49e0e37e235bb0d33bcbcb36af9d1f84abTom Care 2713bfc5f49e0e37e235bb0d33bcbcb36af9d1f84abTom Care // GlibC specific specifiers. 2723bfc5f49e0e37e235bb0d33bcbcb36af9d1f84abTom Care case PrintErrno: return "m"; 2733bfc5f49e0e37e235bb0d33bcbcb36af9d1f84abTom Care } 2743bfc5f49e0e37e235bb0d33bcbcb36af9d1f84abTom Care return NULL; 2753bfc5f49e0e37e235bb0d33bcbcb36af9d1f84abTom Care} 2763bfc5f49e0e37e235bb0d33bcbcb36af9d1f84abTom Care 2773bfc5f49e0e37e235bb0d33bcbcb36af9d1f84abTom Care//===----------------------------------------------------------------------===// 278826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek// Methods on PrintfSpecifier. 27933567d2feb3e52fac6e0b46d5b3d137fc8467fb0Ted Kremenek//===----------------------------------------------------------------------===// 28033567d2feb3e52fac6e0b46d5b3d137fc8467fb0Ted Kremenek 281687b5df89d4ba91219df578d02087c68c09a0332Nick LewyckyArgTypeResult PrintfSpecifier::getArgType(ASTContext &Ctx) const { 2826ecb950c65329f8d6ce9ad0514632df35a5ab61fTed Kremenek const PrintfConversionSpecifier &CS = getConversionSpecifier(); 283dfbb02a16ac8c764b5ba1742450513d6212d2f9fNAKAMURA Takumi 28433567d2feb3e52fac6e0b46d5b3d137fc8467fb0Ted Kremenek if (!CS.consumesDataArgument()) 28533567d2feb3e52fac6e0b46d5b3d137fc8467fb0Ted Kremenek return ArgTypeResult::Invalid(); 2864e4b30ec62d78b24e6556fea2624855c193d0e3eTed Kremenek 2879325eaf08fcccbc0d038e703f570c64daacdaa31Ted Kremenek if (CS.getKind() == ConversionSpecifier::cArg) 2889325eaf08fcccbc0d038e703f570c64daacdaa31Ted Kremenek switch (LM.getKind()) { 2899325eaf08fcccbc0d038e703f570c64daacdaa31Ted Kremenek case LengthModifier::None: return Ctx.IntTy; 2909325eaf08fcccbc0d038e703f570c64daacdaa31Ted Kremenek case LengthModifier::AsLong: return ArgTypeResult::WIntTy; 2919325eaf08fcccbc0d038e703f570c64daacdaa31Ted Kremenek default: 2929325eaf08fcccbc0d038e703f570c64daacdaa31Ted Kremenek return ArgTypeResult::Invalid(); 2939325eaf08fcccbc0d038e703f570c64daacdaa31Ted Kremenek } 294dfbb02a16ac8c764b5ba1742450513d6212d2f9fNAKAMURA Takumi 29533567d2feb3e52fac6e0b46d5b3d137fc8467fb0Ted Kremenek if (CS.isIntArg()) 2963bfc5f49e0e37e235bb0d33bcbcb36af9d1f84abTom Care switch (LM.getKind()) { 2973bfc5f49e0e37e235bb0d33bcbcb36af9d1f84abTom Care case LengthModifier::AsLongDouble: 29833567d2feb3e52fac6e0b46d5b3d137fc8467fb0Ted Kremenek return ArgTypeResult::Invalid(); 2993bfc5f49e0e37e235bb0d33bcbcb36af9d1f84abTom Care case LengthModifier::None: return Ctx.IntTy; 3006ca4a9ae99d65948e578d3e7d1f58ab6a947d2d7Ted Kremenek case LengthModifier::AsChar: return ArgTypeResult::AnyCharTy; 3013bfc5f49e0e37e235bb0d33bcbcb36af9d1f84abTom Care case LengthModifier::AsShort: return Ctx.ShortTy; 3023bfc5f49e0e37e235bb0d33bcbcb36af9d1f84abTom Care case LengthModifier::AsLong: return Ctx.LongTy; 3033bfc5f49e0e37e235bb0d33bcbcb36af9d1f84abTom Care case LengthModifier::AsLongLong: return Ctx.LongLongTy; 304a792aff1c7de253b89c473fdb7eef4a5bba83aecHans Wennborg case LengthModifier::AsIntMax: 305a792aff1c7de253b89c473fdb7eef4a5bba83aecHans Wennborg return ArgTypeResult(Ctx.getIntMaxType(), "intmax_t"); 30629e97cb35fab314388f62b68fefa78947e93c1dcHans Wennborg case LengthModifier::AsSizeT: 30729e97cb35fab314388f62b68fefa78947e93c1dcHans Wennborg // FIXME: How to get the corresponding signed version of size_t? 30833567d2feb3e52fac6e0b46d5b3d137fc8467fb0Ted Kremenek return ArgTypeResult(); 309a792aff1c7de253b89c473fdb7eef4a5bba83aecHans Wennborg case LengthModifier::AsPtrDiff: 310a792aff1c7de253b89c473fdb7eef4a5bba83aecHans Wennborg return ArgTypeResult(Ctx.getPointerDiffType(), "ptrdiff_t"); 31133567d2feb3e52fac6e0b46d5b3d137fc8467fb0Ted Kremenek } 31233567d2feb3e52fac6e0b46d5b3d137fc8467fb0Ted Kremenek 31333567d2feb3e52fac6e0b46d5b3d137fc8467fb0Ted Kremenek if (CS.isUIntArg()) 3143bfc5f49e0e37e235bb0d33bcbcb36af9d1f84abTom Care switch (LM.getKind()) { 3153bfc5f49e0e37e235bb0d33bcbcb36af9d1f84abTom Care case LengthModifier::AsLongDouble: 31633567d2feb3e52fac6e0b46d5b3d137fc8467fb0Ted Kremenek return ArgTypeResult::Invalid(); 3173bfc5f49e0e37e235bb0d33bcbcb36af9d1f84abTom Care case LengthModifier::None: return Ctx.UnsignedIntTy; 3183bfc5f49e0e37e235bb0d33bcbcb36af9d1f84abTom Care case LengthModifier::AsChar: return Ctx.UnsignedCharTy; 3193bfc5f49e0e37e235bb0d33bcbcb36af9d1f84abTom Care case LengthModifier::AsShort: return Ctx.UnsignedShortTy; 3203bfc5f49e0e37e235bb0d33bcbcb36af9d1f84abTom Care case LengthModifier::AsLong: return Ctx.UnsignedLongTy; 3213bfc5f49e0e37e235bb0d33bcbcb36af9d1f84abTom Care case LengthModifier::AsLongLong: return Ctx.UnsignedLongLongTy; 322a792aff1c7de253b89c473fdb7eef4a5bba83aecHans Wennborg case LengthModifier::AsIntMax: 323a792aff1c7de253b89c473fdb7eef4a5bba83aecHans Wennborg return ArgTypeResult(Ctx.getUIntMaxType(), "uintmax_t"); 3243bfc5f49e0e37e235bb0d33bcbcb36af9d1f84abTom Care case LengthModifier::AsSizeT: 325a792aff1c7de253b89c473fdb7eef4a5bba83aecHans Wennborg return ArgTypeResult(Ctx.getSizeType(), "size_t"); 3263bfc5f49e0e37e235bb0d33bcbcb36af9d1f84abTom Care case LengthModifier::AsPtrDiff: 32733567d2feb3e52fac6e0b46d5b3d137fc8467fb0Ted Kremenek // FIXME: How to get the corresponding unsigned 32833567d2feb3e52fac6e0b46d5b3d137fc8467fb0Ted Kremenek // version of ptrdiff_t? 32933567d2feb3e52fac6e0b46d5b3d137fc8467fb0Ted Kremenek return ArgTypeResult(); 33033567d2feb3e52fac6e0b46d5b3d137fc8467fb0Ted Kremenek } 3314e4b30ec62d78b24e6556fea2624855c193d0e3eTed Kremenek 332f911eba72e6d7275e5cfdb79ab23fb2aa9cc01d0Ted Kremenek if (CS.isDoubleArg()) { 3333bfc5f49e0e37e235bb0d33bcbcb36af9d1f84abTom Care if (LM.getKind() == LengthModifier::AsLongDouble) 334f911eba72e6d7275e5cfdb79ab23fb2aa9cc01d0Ted Kremenek return Ctx.LongDoubleTy; 335c9a89fec60a20eb3269caa95eca048d45ab215adTed Kremenek return Ctx.DoubleTy; 336f911eba72e6d7275e5cfdb79ab23fb2aa9cc01d0Ted Kremenek } 3377f70dc85d5055c19c8003f43a59135de211ad1b9Ted Kremenek 33887260c7eabf88eb2009ba2ba20150cd897483241Ted Kremenek switch (CS.getKind()) { 33999196b1031d37d37f395a3291ccdd12a3fc01242Ted Kremenek case ConversionSpecifier::sArg: 3403bfc5f49e0e37e235bb0d33bcbcb36af9d1f84abTom Care return ArgTypeResult(LM.getKind() == LengthModifier::AsWideChar ? 3413bfc5f49e0e37e235bb0d33bcbcb36af9d1f84abTom Care ArgTypeResult::WCStrTy : ArgTypeResult::CStrTy); 342de183a48dd8fcff5e0343e84c8a6b563088447ceTed Kremenek case ConversionSpecifier::SArg: 34387260c7eabf88eb2009ba2ba20150cd897483241Ted Kremenek // FIXME: This appears to be Mac OS X specific. 34487260c7eabf88eb2009ba2ba20150cd897483241Ted Kremenek return ArgTypeResult::WCStrTy; 34587260c7eabf88eb2009ba2ba20150cd897483241Ted Kremenek case ConversionSpecifier::CArg: 3467f70dc85d5055c19c8003f43a59135de211ad1b9Ted Kremenek return Ctx.WCharTy; 34766932056da99d2441e27c10b27c82706671e1dbfTed Kremenek case ConversionSpecifier::pArg: 34813927a431dd733336cfd664bf0840747a71b0a43Ted Kremenek return ArgTypeResult::CPointerTy; 34987260c7eabf88eb2009ba2ba20150cd897483241Ted Kremenek default: 35087260c7eabf88eb2009ba2ba20150cd897483241Ted Kremenek break; 35187260c7eabf88eb2009ba2ba20150cd897483241Ted Kremenek } 3527f70dc85d5055c19c8003f43a59135de211ad1b9Ted Kremenek 35333567d2feb3e52fac6e0b46d5b3d137fc8467fb0Ted Kremenek // FIXME: Handle other cases. 35440888ada6022cfd4ab2a7c07ab276639860ffc5aTed Kremenek return ArgTypeResult(); 35533567d2feb3e52fac6e0b46d5b3d137fc8467fb0Ted Kremenek} 35633567d2feb3e52fac6e0b46d5b3d137fc8467fb0Ted Kremenek 357a7da2155167676a6a5d9fca4de947a9cab2a4908Hans Wennborgbool PrintfSpecifier::fixType(QualType QT, const LangOptions &LangOpt) { 3583bfc5f49e0e37e235bb0d33bcbcb36af9d1f84abTom Care // Handle strings first (char *, wchar_t *) 3593bfc5f49e0e37e235bb0d33bcbcb36af9d1f84abTom Care if (QT->isPointerType() && (QT->getPointeeType()->isAnyCharacterType())) { 36099196b1031d37d37f395a3291ccdd12a3fc01242Ted Kremenek CS.setKind(ConversionSpecifier::sArg); 3613bfc5f49e0e37e235bb0d33bcbcb36af9d1f84abTom Care 362876e994957472eda4b40136d4e1d6e08e2be338fTom Care // Disable irrelevant flags 363876e994957472eda4b40136d4e1d6e08e2be338fTom Care HasAlternativeForm = 0; 364876e994957472eda4b40136d4e1d6e08e2be338fTom Care HasLeadingZeroes = 0; 365876e994957472eda4b40136d4e1d6e08e2be338fTom Care 3663bfc5f49e0e37e235bb0d33bcbcb36af9d1f84abTom Care // Set the long length modifier for wide characters 3673bfc5f49e0e37e235bb0d33bcbcb36af9d1f84abTom Care if (QT->getPointeeType()->isWideCharType()) 3683bfc5f49e0e37e235bb0d33bcbcb36af9d1f84abTom Care LM.setKind(LengthModifier::AsWideChar); 3693bfc5f49e0e37e235bb0d33bcbcb36af9d1f84abTom Care 3703bfc5f49e0e37e235bb0d33bcbcb36af9d1f84abTom Care return true; 3713bfc5f49e0e37e235bb0d33bcbcb36af9d1f84abTom Care } 3723bfc5f49e0e37e235bb0d33bcbcb36af9d1f84abTom Care 3733bfc5f49e0e37e235bb0d33bcbcb36af9d1f84abTom Care // We can only work with builtin types. 3743bfc5f49e0e37e235bb0d33bcbcb36af9d1f84abTom Care const BuiltinType *BT = QT->getAs<BuiltinType>(); 3752dde35bc626153492f5f58202506c88a27fbff5bJohn McCall if (!BT) 3762dde35bc626153492f5f58202506c88a27fbff5bJohn McCall return false; 377876e994957472eda4b40136d4e1d6e08e2be338fTom Care 3783bfc5f49e0e37e235bb0d33bcbcb36af9d1f84abTom Care // Set length modifier 3793bfc5f49e0e37e235bb0d33bcbcb36af9d1f84abTom Care switch (BT->getKind()) { 38006d88ec4204be7af2cf935f39a3e3391d281ad52Eli Friedman case BuiltinType::Bool: 38106d88ec4204be7af2cf935f39a3e3391d281ad52Eli Friedman case BuiltinType::WChar_U: 38206d88ec4204be7af2cf935f39a3e3391d281ad52Eli Friedman case BuiltinType::WChar_S: 38306d88ec4204be7af2cf935f39a3e3391d281ad52Eli Friedman case BuiltinType::Char16: 38406d88ec4204be7af2cf935f39a3e3391d281ad52Eli Friedman case BuiltinType::Char32: 38506d88ec4204be7af2cf935f39a3e3391d281ad52Eli Friedman case BuiltinType::UInt128: 38606d88ec4204be7af2cf935f39a3e3391d281ad52Eli Friedman case BuiltinType::Int128: 387aa4a99b4a62615db243f7a5c433169f2fc704420Anton Korobeynikov case BuiltinType::Half: 3882dde35bc626153492f5f58202506c88a27fbff5bJohn McCall // Various types which are non-trivial to correct. 38906d88ec4204be7af2cf935f39a3e3391d281ad52Eli Friedman return false; 39006d88ec4204be7af2cf935f39a3e3391d281ad52Eli Friedman 3912dde35bc626153492f5f58202506c88a27fbff5bJohn McCall#define SIGNED_TYPE(Id, SingletonId) 3922dde35bc626153492f5f58202506c88a27fbff5bJohn McCall#define UNSIGNED_TYPE(Id, SingletonId) 3932dde35bc626153492f5f58202506c88a27fbff5bJohn McCall#define FLOATING_TYPE(Id, SingletonId) 3942dde35bc626153492f5f58202506c88a27fbff5bJohn McCall#define BUILTIN_TYPE(Id, SingletonId) \ 3952dde35bc626153492f5f58202506c88a27fbff5bJohn McCall case BuiltinType::Id: 3962dde35bc626153492f5f58202506c88a27fbff5bJohn McCall#include "clang/AST/BuiltinTypes.def" 39706d88ec4204be7af2cf935f39a3e3391d281ad52Eli Friedman // Misc other stuff which doesn't make sense here. 39806d88ec4204be7af2cf935f39a3e3391d281ad52Eli Friedman return false; 39906d88ec4204be7af2cf935f39a3e3391d281ad52Eli Friedman 40006d88ec4204be7af2cf935f39a3e3391d281ad52Eli Friedman case BuiltinType::UInt: 40106d88ec4204be7af2cf935f39a3e3391d281ad52Eli Friedman case BuiltinType::Int: 40206d88ec4204be7af2cf935f39a3e3391d281ad52Eli Friedman case BuiltinType::Float: 40306d88ec4204be7af2cf935f39a3e3391d281ad52Eli Friedman case BuiltinType::Double: 404876e994957472eda4b40136d4e1d6e08e2be338fTom Care LM.setKind(LengthModifier::None); 4053bfc5f49e0e37e235bb0d33bcbcb36af9d1f84abTom Care break; 406876e994957472eda4b40136d4e1d6e08e2be338fTom Care 4074d8ae4d57ed18d60da4d3786fb740607aa7c3688Ted Kremenek case BuiltinType::Char_U: 4084d8ae4d57ed18d60da4d3786fb740607aa7c3688Ted Kremenek case BuiltinType::UChar: 4094d8ae4d57ed18d60da4d3786fb740607aa7c3688Ted Kremenek case BuiltinType::Char_S: 4104d8ae4d57ed18d60da4d3786fb740607aa7c3688Ted Kremenek case BuiltinType::SChar: 4114d8ae4d57ed18d60da4d3786fb740607aa7c3688Ted Kremenek LM.setKind(LengthModifier::AsChar); 4124d8ae4d57ed18d60da4d3786fb740607aa7c3688Ted Kremenek break; 4134d8ae4d57ed18d60da4d3786fb740607aa7c3688Ted Kremenek 4144d8ae4d57ed18d60da4d3786fb740607aa7c3688Ted Kremenek case BuiltinType::Short: 4154d8ae4d57ed18d60da4d3786fb740607aa7c3688Ted Kremenek case BuiltinType::UShort: 4164d8ae4d57ed18d60da4d3786fb740607aa7c3688Ted Kremenek LM.setKind(LengthModifier::AsShort); 4174d8ae4d57ed18d60da4d3786fb740607aa7c3688Ted Kremenek break; 4184d8ae4d57ed18d60da4d3786fb740607aa7c3688Ted Kremenek 4193bfc5f49e0e37e235bb0d33bcbcb36af9d1f84abTom Care case BuiltinType::Long: 4203bfc5f49e0e37e235bb0d33bcbcb36af9d1f84abTom Care case BuiltinType::ULong: 4213bfc5f49e0e37e235bb0d33bcbcb36af9d1f84abTom Care LM.setKind(LengthModifier::AsLong); 4223bfc5f49e0e37e235bb0d33bcbcb36af9d1f84abTom Care break; 4233bfc5f49e0e37e235bb0d33bcbcb36af9d1f84abTom Care 4243bfc5f49e0e37e235bb0d33bcbcb36af9d1f84abTom Care case BuiltinType::LongLong: 4253bfc5f49e0e37e235bb0d33bcbcb36af9d1f84abTom Care case BuiltinType::ULongLong: 4263bfc5f49e0e37e235bb0d33bcbcb36af9d1f84abTom Care LM.setKind(LengthModifier::AsLongLong); 4273bfc5f49e0e37e235bb0d33bcbcb36af9d1f84abTom Care break; 4283bfc5f49e0e37e235bb0d33bcbcb36af9d1f84abTom Care 4293bfc5f49e0e37e235bb0d33bcbcb36af9d1f84abTom Care case BuiltinType::LongDouble: 4303bfc5f49e0e37e235bb0d33bcbcb36af9d1f84abTom Care LM.setKind(LengthModifier::AsLongDouble); 4313bfc5f49e0e37e235bb0d33bcbcb36af9d1f84abTom Care break; 4323bfc5f49e0e37e235bb0d33bcbcb36af9d1f84abTom Care } 4333bfc5f49e0e37e235bb0d33bcbcb36af9d1f84abTom Care 434a7da2155167676a6a5d9fca4de947a9cab2a4908Hans Wennborg // Handle size_t, ptrdiff_t, etc. that have dedicated length modifiers in C99. 435a7da2155167676a6a5d9fca4de947a9cab2a4908Hans Wennborg if (isa<TypedefType>(QT) && (LangOpt.C99 || LangOpt.CPlusPlus0x)) { 436a7da2155167676a6a5d9fca4de947a9cab2a4908Hans Wennborg const IdentifierInfo *Identifier = QT.getBaseTypeIdentifier(); 437a7da2155167676a6a5d9fca4de947a9cab2a4908Hans Wennborg if (Identifier->getName() == "size_t") { 438a7da2155167676a6a5d9fca4de947a9cab2a4908Hans Wennborg LM.setKind(LengthModifier::AsSizeT); 439a7da2155167676a6a5d9fca4de947a9cab2a4908Hans Wennborg } else if (Identifier->getName() == "ssize_t") { 440a7da2155167676a6a5d9fca4de947a9cab2a4908Hans Wennborg // Not C99, but common in Unix. 441a7da2155167676a6a5d9fca4de947a9cab2a4908Hans Wennborg LM.setKind(LengthModifier::AsSizeT); 442a7da2155167676a6a5d9fca4de947a9cab2a4908Hans Wennborg } else if (Identifier->getName() == "intmax_t") { 443a7da2155167676a6a5d9fca4de947a9cab2a4908Hans Wennborg LM.setKind(LengthModifier::AsIntMax); 444a7da2155167676a6a5d9fca4de947a9cab2a4908Hans Wennborg } else if (Identifier->getName() == "uintmax_t") { 445a7da2155167676a6a5d9fca4de947a9cab2a4908Hans Wennborg LM.setKind(LengthModifier::AsIntMax); 446a7da2155167676a6a5d9fca4de947a9cab2a4908Hans Wennborg } else if (Identifier->getName() == "ptrdiff_t") { 447a7da2155167676a6a5d9fca4de947a9cab2a4908Hans Wennborg LM.setKind(LengthModifier::AsPtrDiff); 448a7da2155167676a6a5d9fca4de947a9cab2a4908Hans Wennborg } 449a7da2155167676a6a5d9fca4de947a9cab2a4908Hans Wennborg } 450a7da2155167676a6a5d9fca4de947a9cab2a4908Hans Wennborg 4513bfc5f49e0e37e235bb0d33bcbcb36af9d1f84abTom Care // Set conversion specifier and disable any flags which do not apply to it. 4524d8ae4d57ed18d60da4d3786fb740607aa7c3688Ted Kremenek // Let typedefs to char fall through to int, as %c is silly for uint8_t. 4534d8ae4d57ed18d60da4d3786fb740607aa7c3688Ted Kremenek if (isa<TypedefType>(QT) && QT->isAnyCharacterType()) { 45492a6febe130dd9ad726983835297e11b2fa3b93fTed Kremenek CS.setKind(ConversionSpecifier::cArg); 4554d8ae4d57ed18d60da4d3786fb740607aa7c3688Ted Kremenek LM.setKind(LengthModifier::None); 4563bfc5f49e0e37e235bb0d33bcbcb36af9d1f84abTom Care Precision.setHowSpecified(OptionalAmount::NotSpecified); 4573bfc5f49e0e37e235bb0d33bcbcb36af9d1f84abTom Care HasAlternativeForm = 0; 4583bfc5f49e0e37e235bb0d33bcbcb36af9d1f84abTom Care HasLeadingZeroes = 0; 459e4ee9663168dfb2b4122c768091e30217328c9faTom Care HasPlusPrefix = 0; 4603bfc5f49e0e37e235bb0d33bcbcb36af9d1f84abTom Care } 4613bfc5f49e0e37e235bb0d33bcbcb36af9d1f84abTom Care // Test for Floating type first as LongDouble can pass isUnsignedIntegerType 4620c293ea13d452c1a47a05ada5a5ee9acc69c66ccDouglas Gregor else if (QT->isRealFloatingType()) { 4633bfc5f49e0e37e235bb0d33bcbcb36af9d1f84abTom Care CS.setKind(ConversionSpecifier::fArg); 4643bfc5f49e0e37e235bb0d33bcbcb36af9d1f84abTom Care } 4653bfc5f49e0e37e235bb0d33bcbcb36af9d1f84abTom Care else if (QT->isSignedIntegerType()) { 4663bfc5f49e0e37e235bb0d33bcbcb36af9d1f84abTom Care CS.setKind(ConversionSpecifier::dArg); 4673bfc5f49e0e37e235bb0d33bcbcb36af9d1f84abTom Care HasAlternativeForm = 0; 4683bfc5f49e0e37e235bb0d33bcbcb36af9d1f84abTom Care } 469c8c4b4088cf0b3afeda425b25fa7c77d3873b12cDouglas Gregor else if (QT->isUnsignedIntegerType()) { 4701e713f50e904b96623425efa7119fcb98243e111Ted Kremenek // Preserve the original formatting, e.g. 'X', 'o'. 4711e713f50e904b96623425efa7119fcb98243e111Ted Kremenek if (!cast<PrintfConversionSpecifier>(CS).isUIntArg()) 4721e713f50e904b96623425efa7119fcb98243e111Ted Kremenek CS.setKind(ConversionSpecifier::uArg); 4733bfc5f49e0e37e235bb0d33bcbcb36af9d1f84abTom Care HasAlternativeForm = 0; 474e4ee9663168dfb2b4122c768091e30217328c9faTom Care HasPlusPrefix = 0; 4753060178ad9df29789505c1e6debcfc80a3a13587Chad Rosier } else { 476b219cfc4d75f0a03630b7c4509ef791b7e97b2c8David Blaikie llvm_unreachable("Unexpected type"); 4773bfc5f49e0e37e235bb0d33bcbcb36af9d1f84abTom Care } 4783bfc5f49e0e37e235bb0d33bcbcb36af9d1f84abTom Care 4793bfc5f49e0e37e235bb0d33bcbcb36af9d1f84abTom Care return true; 4803bfc5f49e0e37e235bb0d33bcbcb36af9d1f84abTom Care} 4813bfc5f49e0e37e235bb0d33bcbcb36af9d1f84abTom Care 4825f9e272e632e951b1efe824cd16acb4d96077930Chris Lattnervoid PrintfSpecifier::toString(raw_ostream &os) const { 4833bfc5f49e0e37e235bb0d33bcbcb36af9d1f84abTom Care // Whilst some features have no defined order, we are using the order 4840099530a2288df7c2140dd8992b7310b9f6930a9NAKAMURA Takumi // appearing in the C99 standard (ISO/IEC 9899:1999 (E) 7.19.6.1) 4853bfc5f49e0e37e235bb0d33bcbcb36af9d1f84abTom Care os << "%"; 4863bfc5f49e0e37e235bb0d33bcbcb36af9d1f84abTom Care 4873bfc5f49e0e37e235bb0d33bcbcb36af9d1f84abTom Care // Positional args 4883bfc5f49e0e37e235bb0d33bcbcb36af9d1f84abTom Care if (usesPositionalArg()) { 4893bfc5f49e0e37e235bb0d33bcbcb36af9d1f84abTom Care os << getPositionalArgIndex() << "$"; 4903bfc5f49e0e37e235bb0d33bcbcb36af9d1f84abTom Care } 4913bfc5f49e0e37e235bb0d33bcbcb36af9d1f84abTom Care 4923bfc5f49e0e37e235bb0d33bcbcb36af9d1f84abTom Care // Conversion flags 4933bfc5f49e0e37e235bb0d33bcbcb36af9d1f84abTom Care if (IsLeftJustified) os << "-"; 4943bfc5f49e0e37e235bb0d33bcbcb36af9d1f84abTom Care if (HasPlusPrefix) os << "+"; 4953bfc5f49e0e37e235bb0d33bcbcb36af9d1f84abTom Care if (HasSpacePrefix) os << " "; 4963bfc5f49e0e37e235bb0d33bcbcb36af9d1f84abTom Care if (HasAlternativeForm) os << "#"; 4973bfc5f49e0e37e235bb0d33bcbcb36af9d1f84abTom Care if (HasLeadingZeroes) os << "0"; 4983bfc5f49e0e37e235bb0d33bcbcb36af9d1f84abTom Care 4993bfc5f49e0e37e235bb0d33bcbcb36af9d1f84abTom Care // Minimum field width 5003bfc5f49e0e37e235bb0d33bcbcb36af9d1f84abTom Care FieldWidth.toString(os); 5013bfc5f49e0e37e235bb0d33bcbcb36af9d1f84abTom Care // Precision 5023bfc5f49e0e37e235bb0d33bcbcb36af9d1f84abTom Care Precision.toString(os); 5033bfc5f49e0e37e235bb0d33bcbcb36af9d1f84abTom Care // Length modifier 5043bfc5f49e0e37e235bb0d33bcbcb36af9d1f84abTom Care os << LM.toString(); 5053bfc5f49e0e37e235bb0d33bcbcb36af9d1f84abTom Care // Conversion specifier 5063bfc5f49e0e37e235bb0d33bcbcb36af9d1f84abTom Care os << CS.toString(); 5073bfc5f49e0e37e235bb0d33bcbcb36af9d1f84abTom Care} 508e4ee9663168dfb2b4122c768091e30217328c9faTom Care 509826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenekbool PrintfSpecifier::hasValidPlusPrefix() const { 510e4ee9663168dfb2b4122c768091e30217328c9faTom Care if (!HasPlusPrefix) 511e4ee9663168dfb2b4122c768091e30217328c9faTom Care return true; 512e4ee9663168dfb2b4122c768091e30217328c9faTom Care 513e4ee9663168dfb2b4122c768091e30217328c9faTom Care // The plus prefix only makes sense for signed conversions 514e4ee9663168dfb2b4122c768091e30217328c9faTom Care switch (CS.getKind()) { 515e4ee9663168dfb2b4122c768091e30217328c9faTom Care case ConversionSpecifier::dArg: 516e4ee9663168dfb2b4122c768091e30217328c9faTom Care case ConversionSpecifier::iArg: 517e4ee9663168dfb2b4122c768091e30217328c9faTom Care case ConversionSpecifier::fArg: 518e4ee9663168dfb2b4122c768091e30217328c9faTom Care case ConversionSpecifier::FArg: 519e4ee9663168dfb2b4122c768091e30217328c9faTom Care case ConversionSpecifier::eArg: 520e4ee9663168dfb2b4122c768091e30217328c9faTom Care case ConversionSpecifier::EArg: 521e4ee9663168dfb2b4122c768091e30217328c9faTom Care case ConversionSpecifier::gArg: 522e4ee9663168dfb2b4122c768091e30217328c9faTom Care case ConversionSpecifier::GArg: 523e4ee9663168dfb2b4122c768091e30217328c9faTom Care case ConversionSpecifier::aArg: 524e4ee9663168dfb2b4122c768091e30217328c9faTom Care case ConversionSpecifier::AArg: 525e4ee9663168dfb2b4122c768091e30217328c9faTom Care return true; 526e4ee9663168dfb2b4122c768091e30217328c9faTom Care 527e4ee9663168dfb2b4122c768091e30217328c9faTom Care default: 528e4ee9663168dfb2b4122c768091e30217328c9faTom Care return false; 529e4ee9663168dfb2b4122c768091e30217328c9faTom Care } 530e4ee9663168dfb2b4122c768091e30217328c9faTom Care} 531e4ee9663168dfb2b4122c768091e30217328c9faTom Care 532826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenekbool PrintfSpecifier::hasValidAlternativeForm() const { 533e4ee9663168dfb2b4122c768091e30217328c9faTom Care if (!HasAlternativeForm) 534e4ee9663168dfb2b4122c768091e30217328c9faTom Care return true; 535e4ee9663168dfb2b4122c768091e30217328c9faTom Care 5362e6c19abcf97c25f4d7458a9db89c5ab0158717dAnders Carlsson // Alternate form flag only valid with the oxXaAeEfFgG conversions 537e4ee9663168dfb2b4122c768091e30217328c9faTom Care switch (CS.getKind()) { 538e4ee9663168dfb2b4122c768091e30217328c9faTom Care case ConversionSpecifier::oArg: 539e4ee9663168dfb2b4122c768091e30217328c9faTom Care case ConversionSpecifier::xArg: 5402e6c19abcf97c25f4d7458a9db89c5ab0158717dAnders Carlsson case ConversionSpecifier::XArg: 541e4ee9663168dfb2b4122c768091e30217328c9faTom Care case ConversionSpecifier::aArg: 542e4ee9663168dfb2b4122c768091e30217328c9faTom Care case ConversionSpecifier::AArg: 543e4ee9663168dfb2b4122c768091e30217328c9faTom Care case ConversionSpecifier::eArg: 544e4ee9663168dfb2b4122c768091e30217328c9faTom Care case ConversionSpecifier::EArg: 545e4ee9663168dfb2b4122c768091e30217328c9faTom Care case ConversionSpecifier::fArg: 546e4ee9663168dfb2b4122c768091e30217328c9faTom Care case ConversionSpecifier::FArg: 547e4ee9663168dfb2b4122c768091e30217328c9faTom Care case ConversionSpecifier::gArg: 548e4ee9663168dfb2b4122c768091e30217328c9faTom Care case ConversionSpecifier::GArg: 549e4ee9663168dfb2b4122c768091e30217328c9faTom Care return true; 550e4ee9663168dfb2b4122c768091e30217328c9faTom Care 551e4ee9663168dfb2b4122c768091e30217328c9faTom Care default: 552e4ee9663168dfb2b4122c768091e30217328c9faTom Care return false; 553e4ee9663168dfb2b4122c768091e30217328c9faTom Care } 554e4ee9663168dfb2b4122c768091e30217328c9faTom Care} 555e4ee9663168dfb2b4122c768091e30217328c9faTom Care 556826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenekbool PrintfSpecifier::hasValidLeadingZeros() const { 557e4ee9663168dfb2b4122c768091e30217328c9faTom Care if (!HasLeadingZeroes) 558e4ee9663168dfb2b4122c768091e30217328c9faTom Care return true; 559e4ee9663168dfb2b4122c768091e30217328c9faTom Care 560e4ee9663168dfb2b4122c768091e30217328c9faTom Care // Leading zeroes flag only valid with the diouxXaAeEfFgG conversions 561e4ee9663168dfb2b4122c768091e30217328c9faTom Care switch (CS.getKind()) { 562e4ee9663168dfb2b4122c768091e30217328c9faTom Care case ConversionSpecifier::dArg: 563e4ee9663168dfb2b4122c768091e30217328c9faTom Care case ConversionSpecifier::iArg: 564e4ee9663168dfb2b4122c768091e30217328c9faTom Care case ConversionSpecifier::oArg: 565e4ee9663168dfb2b4122c768091e30217328c9faTom Care case ConversionSpecifier::uArg: 566e4ee9663168dfb2b4122c768091e30217328c9faTom Care case ConversionSpecifier::xArg: 567e4ee9663168dfb2b4122c768091e30217328c9faTom Care case ConversionSpecifier::XArg: 568e4ee9663168dfb2b4122c768091e30217328c9faTom Care case ConversionSpecifier::aArg: 569e4ee9663168dfb2b4122c768091e30217328c9faTom Care case ConversionSpecifier::AArg: 570e4ee9663168dfb2b4122c768091e30217328c9faTom Care case ConversionSpecifier::eArg: 571e4ee9663168dfb2b4122c768091e30217328c9faTom Care case ConversionSpecifier::EArg: 572e4ee9663168dfb2b4122c768091e30217328c9faTom Care case ConversionSpecifier::fArg: 573e4ee9663168dfb2b4122c768091e30217328c9faTom Care case ConversionSpecifier::FArg: 574e4ee9663168dfb2b4122c768091e30217328c9faTom Care case ConversionSpecifier::gArg: 575e4ee9663168dfb2b4122c768091e30217328c9faTom Care case ConversionSpecifier::GArg: 576e4ee9663168dfb2b4122c768091e30217328c9faTom Care return true; 577e4ee9663168dfb2b4122c768091e30217328c9faTom Care 578e4ee9663168dfb2b4122c768091e30217328c9faTom Care default: 579e4ee9663168dfb2b4122c768091e30217328c9faTom Care return false; 580e4ee9663168dfb2b4122c768091e30217328c9faTom Care } 581e4ee9663168dfb2b4122c768091e30217328c9faTom Care} 582e4ee9663168dfb2b4122c768091e30217328c9faTom Care 583826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenekbool PrintfSpecifier::hasValidSpacePrefix() const { 584e4ee9663168dfb2b4122c768091e30217328c9faTom Care if (!HasSpacePrefix) 585e4ee9663168dfb2b4122c768091e30217328c9faTom Care return true; 586e4ee9663168dfb2b4122c768091e30217328c9faTom Care 587e4ee9663168dfb2b4122c768091e30217328c9faTom Care // The space prefix only makes sense for signed conversions 588e4ee9663168dfb2b4122c768091e30217328c9faTom Care switch (CS.getKind()) { 589e4ee9663168dfb2b4122c768091e30217328c9faTom Care case ConversionSpecifier::dArg: 590e4ee9663168dfb2b4122c768091e30217328c9faTom Care case ConversionSpecifier::iArg: 591e4ee9663168dfb2b4122c768091e30217328c9faTom Care case ConversionSpecifier::fArg: 592e4ee9663168dfb2b4122c768091e30217328c9faTom Care case ConversionSpecifier::FArg: 593e4ee9663168dfb2b4122c768091e30217328c9faTom Care case ConversionSpecifier::eArg: 594e4ee9663168dfb2b4122c768091e30217328c9faTom Care case ConversionSpecifier::EArg: 595e4ee9663168dfb2b4122c768091e30217328c9faTom Care case ConversionSpecifier::gArg: 596e4ee9663168dfb2b4122c768091e30217328c9faTom Care case ConversionSpecifier::GArg: 597e4ee9663168dfb2b4122c768091e30217328c9faTom Care case ConversionSpecifier::aArg: 598e4ee9663168dfb2b4122c768091e30217328c9faTom Care case ConversionSpecifier::AArg: 599e4ee9663168dfb2b4122c768091e30217328c9faTom Care return true; 600e4ee9663168dfb2b4122c768091e30217328c9faTom Care 601e4ee9663168dfb2b4122c768091e30217328c9faTom Care default: 602e4ee9663168dfb2b4122c768091e30217328c9faTom Care return false; 603e4ee9663168dfb2b4122c768091e30217328c9faTom Care } 604e4ee9663168dfb2b4122c768091e30217328c9faTom Care} 605e4ee9663168dfb2b4122c768091e30217328c9faTom Care 606826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenekbool PrintfSpecifier::hasValidLeftJustified() const { 607e4ee9663168dfb2b4122c768091e30217328c9faTom Care if (!IsLeftJustified) 608e4ee9663168dfb2b4122c768091e30217328c9faTom Care return true; 609e4ee9663168dfb2b4122c768091e30217328c9faTom Care 610e4ee9663168dfb2b4122c768091e30217328c9faTom Care // The left justified flag is valid for all conversions except n 611e4ee9663168dfb2b4122c768091e30217328c9faTom Care switch (CS.getKind()) { 61235d353b47bce29200b910371dd9b8ba7f3058ab8Ted Kremenek case ConversionSpecifier::nArg: 613e4ee9663168dfb2b4122c768091e30217328c9faTom Care return false; 614e4ee9663168dfb2b4122c768091e30217328c9faTom Care 615e4ee9663168dfb2b4122c768091e30217328c9faTom Care default: 616e4ee9663168dfb2b4122c768091e30217328c9faTom Care return true; 617e4ee9663168dfb2b4122c768091e30217328c9faTom Care } 618e4ee9663168dfb2b4122c768091e30217328c9faTom Care} 619e4ee9663168dfb2b4122c768091e30217328c9faTom Care 62065197b4b0c55bb74af0450230d61ee9461223721Ted Kremenekbool PrintfSpecifier::hasValidThousandsGroupingPrefix() const { 62165197b4b0c55bb74af0450230d61ee9461223721Ted Kremenek if (!HasThousandsGrouping) 62265197b4b0c55bb74af0450230d61ee9461223721Ted Kremenek return true; 623dfbb02a16ac8c764b5ba1742450513d6212d2f9fNAKAMURA Takumi 62465197b4b0c55bb74af0450230d61ee9461223721Ted Kremenek switch (CS.getKind()) { 62565197b4b0c55bb74af0450230d61ee9461223721Ted Kremenek case ConversionSpecifier::dArg: 62665197b4b0c55bb74af0450230d61ee9461223721Ted Kremenek case ConversionSpecifier::iArg: 62765197b4b0c55bb74af0450230d61ee9461223721Ted Kremenek case ConversionSpecifier::uArg: 62865197b4b0c55bb74af0450230d61ee9461223721Ted Kremenek case ConversionSpecifier::fArg: 62965197b4b0c55bb74af0450230d61ee9461223721Ted Kremenek case ConversionSpecifier::FArg: 63065197b4b0c55bb74af0450230d61ee9461223721Ted Kremenek case ConversionSpecifier::gArg: 63165197b4b0c55bb74af0450230d61ee9461223721Ted Kremenek case ConversionSpecifier::GArg: 63265197b4b0c55bb74af0450230d61ee9461223721Ted Kremenek return true; 63365197b4b0c55bb74af0450230d61ee9461223721Ted Kremenek default: 63465197b4b0c55bb74af0450230d61ee9461223721Ted Kremenek return false; 63565197b4b0c55bb74af0450230d61ee9461223721Ted Kremenek } 63665197b4b0c55bb74af0450230d61ee9461223721Ted Kremenek} 63765197b4b0c55bb74af0450230d61ee9461223721Ted Kremenek 638826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenekbool PrintfSpecifier::hasValidPrecision() const { 639e4ee9663168dfb2b4122c768091e30217328c9faTom Care if (Precision.getHowSpecified() == OptionalAmount::NotSpecified) 640e4ee9663168dfb2b4122c768091e30217328c9faTom Care return true; 641e4ee9663168dfb2b4122c768091e30217328c9faTom Care 642e4ee9663168dfb2b4122c768091e30217328c9faTom Care // Precision is only valid with the diouxXaAeEfFgGs conversions 643e4ee9663168dfb2b4122c768091e30217328c9faTom Care switch (CS.getKind()) { 644e4ee9663168dfb2b4122c768091e30217328c9faTom Care case ConversionSpecifier::dArg: 645e4ee9663168dfb2b4122c768091e30217328c9faTom Care case ConversionSpecifier::iArg: 646e4ee9663168dfb2b4122c768091e30217328c9faTom Care case ConversionSpecifier::oArg: 647e4ee9663168dfb2b4122c768091e30217328c9faTom Care case ConversionSpecifier::uArg: 648e4ee9663168dfb2b4122c768091e30217328c9faTom Care case ConversionSpecifier::xArg: 649e4ee9663168dfb2b4122c768091e30217328c9faTom Care case ConversionSpecifier::XArg: 650e4ee9663168dfb2b4122c768091e30217328c9faTom Care case ConversionSpecifier::aArg: 651e4ee9663168dfb2b4122c768091e30217328c9faTom Care case ConversionSpecifier::AArg: 652e4ee9663168dfb2b4122c768091e30217328c9faTom Care case ConversionSpecifier::eArg: 653e4ee9663168dfb2b4122c768091e30217328c9faTom Care case ConversionSpecifier::EArg: 654e4ee9663168dfb2b4122c768091e30217328c9faTom Care case ConversionSpecifier::fArg: 655e4ee9663168dfb2b4122c768091e30217328c9faTom Care case ConversionSpecifier::FArg: 656e4ee9663168dfb2b4122c768091e30217328c9faTom Care case ConversionSpecifier::gArg: 657e4ee9663168dfb2b4122c768091e30217328c9faTom Care case ConversionSpecifier::GArg: 65899196b1031d37d37f395a3291ccdd12a3fc01242Ted Kremenek case ConversionSpecifier::sArg: 659e4ee9663168dfb2b4122c768091e30217328c9faTom Care return true; 660e4ee9663168dfb2b4122c768091e30217328c9faTom Care 661e4ee9663168dfb2b4122c768091e30217328c9faTom Care default: 662e4ee9663168dfb2b4122c768091e30217328c9faTom Care return false; 663e4ee9663168dfb2b4122c768091e30217328c9faTom Care } 664e4ee9663168dfb2b4122c768091e30217328c9faTom Care} 665826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenekbool PrintfSpecifier::hasValidFieldWidth() const { 666e4ee9663168dfb2b4122c768091e30217328c9faTom Care if (FieldWidth.getHowSpecified() == OptionalAmount::NotSpecified) 667e4ee9663168dfb2b4122c768091e30217328c9faTom Care return true; 668e4ee9663168dfb2b4122c768091e30217328c9faTom Care 669e4ee9663168dfb2b4122c768091e30217328c9faTom Care // The field width is valid for all conversions except n 670e4ee9663168dfb2b4122c768091e30217328c9faTom Care switch (CS.getKind()) { 67135d353b47bce29200b910371dd9b8ba7f3058ab8Ted Kremenek case ConversionSpecifier::nArg: 672e4ee9663168dfb2b4122c768091e30217328c9faTom Care return false; 673e4ee9663168dfb2b4122c768091e30217328c9faTom Care 674e4ee9663168dfb2b4122c768091e30217328c9faTom Care default: 675e4ee9663168dfb2b4122c768091e30217328c9faTom Care return true; 676e4ee9663168dfb2b4122c768091e30217328c9faTom Care } 677e4ee9663168dfb2b4122c768091e30217328c9faTom Care} 678