PrintfFormatString.cpp revision dfbb02a16ac8c764b5ba1742450513d6212d2f9f
1aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey//== PrintfFormatString.cpp - Analysis of printf format strings --*- C++ -*-==// 2aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey// 3aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey// The LLVM Compiler Infrastructure 4aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey// 5aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey// This file is distributed under the University of Illinois Open Source 6aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey// License. See LICENSE.TXT for details. 7aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey// 8aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey//===----------------------------------------------------------------------===// 9aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey// 10aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey// Handling of format string in printf and friends. The structure of format 11aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey// strings for fprintf() are described in C99 7.19.6.1. 12aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey// 13aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey//===----------------------------------------------------------------------===// 14aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey 15aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey#include "clang/Analysis/Analyses/FormatString.h" 16aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey#include "FormatStringParsing.h" 17aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey 18aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkeyusing clang::analyze_format_string::ArgTypeResult; 19aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkeyusing clang::analyze_format_string::FormatStringHandler; 20aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkeyusing clang::analyze_format_string::LengthModifier; 21b7e1255d5c8d9e4fa8dd389afb9f5aab35434df3Jeff Sharkeyusing clang::analyze_format_string::OptionalAmount; 22b9fbb7290b02de1ce621deaa2d28a5e42f2e0937Jeff Sharkeyusing clang::analyze_format_string::ConversionSpecifier; 23b9fbb7290b02de1ce621deaa2d28a5e42f2e0937Jeff Sharkeyusing clang::analyze_printf::PrintfSpecifier; 24b9fbb7290b02de1ce621deaa2d28a5e42f2e0937Jeff Sharkey 25ae9b51bfa313c51a31af30875a71255d7b6d2e61Jeff Sharkeyusing namespace clang; 26ae9b51bfa313c51a31af30875a71255d7b6d2e61Jeff Sharkey 27ae9b51bfa313c51a31af30875a71255d7b6d2e61Jeff Sharkeytypedef clang::analyze_format_string::SpecifierResult<PrintfSpecifier> 28b9fbb7290b02de1ce621deaa2d28a5e42f2e0937Jeff Sharkey PrintfSpecifierResult; 29b9fbb7290b02de1ce621deaa2d28a5e42f2e0937Jeff Sharkey 30aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey//===----------------------------------------------------------------------===// 31aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey// Methods for parsing format strings. 32e8c00d8ed477e199b7f8d1b1e2f37e9cf8593372Jeff Sharkey//===----------------------------------------------------------------------===// 33aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey 34aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkeyusing analyze_format_string::ParseNonPositionAmount; 35aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey 36aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkeystatic bool ParsePrecision(FormatStringHandler &H, PrintfSpecifier &FS, 37e37ea6123d1aa3cd3e8804988886b1f6046d79d6Jeff Sharkey const char *Start, const char *&Beg, const char *E, 38aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey unsigned *argIndex) { 39aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey if (argIndex) { 40aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey FS.setPrecision(ParseNonPositionAmount(Beg, E, *argIndex)); 41aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey } 42aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey else { 43aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey const OptionalAmount Amt = ParsePositionAmount(H, Start, Beg, E, 44aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey analyze_format_string::PrecisionPos); 45aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey if (Amt.isInvalid()) 46aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey return true; 47ae9b51bfa313c51a31af30875a71255d7b6d2e61Jeff Sharkey FS.setPrecision(Amt); 48e8c00d8ed477e199b7f8d1b1e2f37e9cf8593372Jeff Sharkey } 49aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey return false; 50aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey} 51aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey 52aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkeystatic PrintfSpecifierResult ParsePrintfSpecifier(FormatStringHandler &H, 53aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey const char *&Beg, 5421de56a94668e0fda1b8bb4ee4f99a09b40d28fdJeff Sharkey const char *E, 55aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey unsigned &argIndex) { 56aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey 57e8c00d8ed477e199b7f8d1b1e2f37e9cf8593372Jeff Sharkey using namespace clang::analyze_format_string; 58e8c00d8ed477e199b7f8d1b1e2f37e9cf8593372Jeff Sharkey using namespace clang::analyze_printf; 59e8c00d8ed477e199b7f8d1b1e2f37e9cf8593372Jeff Sharkey 60e8c00d8ed477e199b7f8d1b1e2f37e9cf8593372Jeff Sharkey const char *I = Beg; 61e8c00d8ed477e199b7f8d1b1e2f37e9cf8593372Jeff Sharkey const char *Start = 0; 62e8c00d8ed477e199b7f8d1b1e2f37e9cf8593372Jeff Sharkey UpdateOnReturn <const char*> UpdateBeg(Beg, I); 63e8c00d8ed477e199b7f8d1b1e2f37e9cf8593372Jeff Sharkey 64e8c00d8ed477e199b7f8d1b1e2f37e9cf8593372Jeff Sharkey // Look for a '%' character that indicates the start of a format specifier. 65e8c00d8ed477e199b7f8d1b1e2f37e9cf8593372Jeff Sharkey for ( ; I != E ; ++I) { 66e8c00d8ed477e199b7f8d1b1e2f37e9cf8593372Jeff Sharkey char c = *I; 67e8c00d8ed477e199b7f8d1b1e2f37e9cf8593372Jeff Sharkey if (c == '\0') { 68e8c00d8ed477e199b7f8d1b1e2f37e9cf8593372Jeff Sharkey // Detect spurious null characters, which are likely errors. 69e8c00d8ed477e199b7f8d1b1e2f37e9cf8593372Jeff Sharkey H.HandleNullChar(I); 70e8c00d8ed477e199b7f8d1b1e2f37e9cf8593372Jeff Sharkey return true; 713b945405cf96eae8b882f87934222a453718a559Jeff Sharkey } 723b945405cf96eae8b882f87934222a453718a559Jeff Sharkey if (c == '%') { 73e8c00d8ed477e199b7f8d1b1e2f37e9cf8593372Jeff Sharkey Start = I++; // Record the start of the format specifier. 74e8c00d8ed477e199b7f8d1b1e2f37e9cf8593372Jeff Sharkey break; 75e8c00d8ed477e199b7f8d1b1e2f37e9cf8593372Jeff Sharkey } 76e8c00d8ed477e199b7f8d1b1e2f37e9cf8593372Jeff Sharkey } 77e8c00d8ed477e199b7f8d1b1e2f37e9cf8593372Jeff Sharkey 78e8c00d8ed477e199b7f8d1b1e2f37e9cf8593372Jeff Sharkey // No format specifier found? 79e8c00d8ed477e199b7f8d1b1e2f37e9cf8593372Jeff Sharkey if (!Start) 80aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey return false; 81e8c00d8ed477e199b7f8d1b1e2f37e9cf8593372Jeff Sharkey 82e8c00d8ed477e199b7f8d1b1e2f37e9cf8593372Jeff Sharkey if (I == E) { 83e8c00d8ed477e199b7f8d1b1e2f37e9cf8593372Jeff Sharkey // No more characters left? 84e8c00d8ed477e199b7f8d1b1e2f37e9cf8593372Jeff Sharkey H.HandleIncompleteSpecifier(Start, E - Start); 85e8c00d8ed477e199b7f8d1b1e2f37e9cf8593372Jeff Sharkey return true; 869352c383e95c3e1facd8a7a2d49ff488fb7bbcafJeff Sharkey } 879352c383e95c3e1facd8a7a2d49ff488fb7bbcafJeff Sharkey 88e8c00d8ed477e199b7f8d1b1e2f37e9cf8593372Jeff Sharkey PrintfSpecifier FS; 89e8c00d8ed477e199b7f8d1b1e2f37e9cf8593372Jeff Sharkey if (ParseArgPosition(H, FS, Start, I, E)) 90aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey return true; 91e8c00d8ed477e199b7f8d1b1e2f37e9cf8593372Jeff Sharkey 92aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey if (I == E) { 93e8c00d8ed477e199b7f8d1b1e2f37e9cf8593372Jeff Sharkey // No more characters left? 94e8c00d8ed477e199b7f8d1b1e2f37e9cf8593372Jeff Sharkey H.HandleIncompleteSpecifier(Start, E - Start); 95e8c00d8ed477e199b7f8d1b1e2f37e9cf8593372Jeff Sharkey return true; 96e8c00d8ed477e199b7f8d1b1e2f37e9cf8593372Jeff Sharkey } 97e8c00d8ed477e199b7f8d1b1e2f37e9cf8593372Jeff Sharkey 98e8c00d8ed477e199b7f8d1b1e2f37e9cf8593372Jeff Sharkey // Look for flags (if any). 99e8c00d8ed477e199b7f8d1b1e2f37e9cf8593372Jeff Sharkey bool hasMore = true; 1009352c383e95c3e1facd8a7a2d49ff488fb7bbcafJeff Sharkey for ( ; I != E; ++I) { 1019352c383e95c3e1facd8a7a2d49ff488fb7bbcafJeff Sharkey switch (*I) { 102e8c00d8ed477e199b7f8d1b1e2f37e9cf8593372Jeff Sharkey default: hasMore = false; break; 103e8c00d8ed477e199b7f8d1b1e2f37e9cf8593372Jeff Sharkey case '\'': 104e8c00d8ed477e199b7f8d1b1e2f37e9cf8593372Jeff Sharkey // FIXME: POSIX specific. Always accept? 105e8c00d8ed477e199b7f8d1b1e2f37e9cf8593372Jeff Sharkey FS.setHasThousandsGrouping(I); 106e8c00d8ed477e199b7f8d1b1e2f37e9cf8593372Jeff Sharkey break; 107e8c00d8ed477e199b7f8d1b1e2f37e9cf8593372Jeff Sharkey case '-': FS.setIsLeftJustified(I); break; 108e8c00d8ed477e199b7f8d1b1e2f37e9cf8593372Jeff Sharkey case '+': FS.setHasPlusPrefix(I); break; 109e8c00d8ed477e199b7f8d1b1e2f37e9cf8593372Jeff Sharkey case ' ': FS.setHasSpacePrefix(I); break; 110e8c00d8ed477e199b7f8d1b1e2f37e9cf8593372Jeff Sharkey case '#': FS.setHasAlternativeForm(I); break; 1119352c383e95c3e1facd8a7a2d49ff488fb7bbcafJeff Sharkey case '0': FS.setHasLeadingZeros(I); break; 112e8c00d8ed477e199b7f8d1b1e2f37e9cf8593372Jeff Sharkey } 113e8c00d8ed477e199b7f8d1b1e2f37e9cf8593372Jeff Sharkey if (!hasMore) 114aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey break; 115e8c00d8ed477e199b7f8d1b1e2f37e9cf8593372Jeff Sharkey } 116e8c00d8ed477e199b7f8d1b1e2f37e9cf8593372Jeff Sharkey 117e8c00d8ed477e199b7f8d1b1e2f37e9cf8593372Jeff Sharkey if (I == E) { 118e8c00d8ed477e199b7f8d1b1e2f37e9cf8593372Jeff Sharkey // No more characters left? 119e8c00d8ed477e199b7f8d1b1e2f37e9cf8593372Jeff Sharkey H.HandleIncompleteSpecifier(Start, E - Start); 120e8c00d8ed477e199b7f8d1b1e2f37e9cf8593372Jeff Sharkey return true; 121aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey } 122aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey 123b9fbb7290b02de1ce621deaa2d28a5e42f2e0937Jeff Sharkey // Look for the field width (if any). 124aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey if (ParseFieldWidth(H, FS, Start, I, E, 125aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey FS.usesPositionalArg() ? 0 : &argIndex)) 126aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey return true; 127aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey 128aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey if (I == E) { 129a61dc8e03e6e863005b3a4629ca8f3801d33d3c4Jeff Sharkey // No more characters left? 130a61dc8e03e6e863005b3a4629ca8f3801d33d3c4Jeff Sharkey H.HandleIncompleteSpecifier(Start, E - Start); 131a61dc8e03e6e863005b3a4629ca8f3801d33d3c4Jeff Sharkey return true; 1323e1189b3590aefb65a2af720ae2ba959bbd4188dJeff Sharkey } 1333e1189b3590aefb65a2af720ae2ba959bbd4188dJeff Sharkey 1343e1189b3590aefb65a2af720ae2ba959bbd4188dJeff Sharkey // Look for the precision (if any). 135b9fbb7290b02de1ce621deaa2d28a5e42f2e0937Jeff Sharkey if (*I == '.') { 136b9fbb7290b02de1ce621deaa2d28a5e42f2e0937Jeff Sharkey ++I; 137aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey if (I == E) { 138aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey H.HandleIncompleteSpecifier(Start, E - Start); 139aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey return true; 140aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey } 141aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey 142ae9b51bfa313c51a31af30875a71255d7b6d2e61Jeff Sharkey if (ParsePrecision(H, FS, Start, I, E, 143ae9b51bfa313c51a31af30875a71255d7b6d2e61Jeff Sharkey FS.usesPositionalArg() ? 0 : &argIndex)) 144ae9b51bfa313c51a31af30875a71255d7b6d2e61Jeff Sharkey return true; 145aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey 146aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey if (I == E) { 147aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey // No more characters left? 148aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey H.HandleIncompleteSpecifier(Start, E - Start); 149aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey return true; 150a61dc8e03e6e863005b3a4629ca8f3801d33d3c4Jeff Sharkey } 151a61dc8e03e6e863005b3a4629ca8f3801d33d3c4Jeff Sharkey } 152ae9b51bfa313c51a31af30875a71255d7b6d2e61Jeff Sharkey 1533e1189b3590aefb65a2af720ae2ba959bbd4188dJeff Sharkey // Look for the length modifier. 154ae9b51bfa313c51a31af30875a71255d7b6d2e61Jeff Sharkey if (ParseLengthModifier(FS, I, E) && I == E) { 155ae9b51bfa313c51a31af30875a71255d7b6d2e61Jeff Sharkey // No more characters left? 156b9fbb7290b02de1ce621deaa2d28a5e42f2e0937Jeff Sharkey H.HandleIncompleteSpecifier(Start, E - Start); 157b9fbb7290b02de1ce621deaa2d28a5e42f2e0937Jeff Sharkey return true; 158aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey } 159aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey 160aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey if (*I == '\0') { 161aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey // Detect spurious null characters, which are likely errors. 162aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey H.HandleNullChar(I); 163aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey return true; 164aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey } 165aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey 166aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey // Finally, look for the conversion specifier. 167aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey const char *conversionPosition = I++; 168aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey ConversionSpecifier::Kind k = ConversionSpecifier::InvalidSpecifier; 169aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey switch (*conversionPosition) { 170aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey default: 171aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey break; 172aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey // C99: 7.19.6.1 (section 8). 173aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey case '%': k = ConversionSpecifier::PercentArg; break; 174aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey case 'A': k = ConversionSpecifier::AArg; break; 17521de56a94668e0fda1b8bb4ee4f99a09b40d28fdJeff Sharkey case 'E': k = ConversionSpecifier::EArg; break; 176b9fbb7290b02de1ce621deaa2d28a5e42f2e0937Jeff Sharkey case 'F': k = ConversionSpecifier::FArg; break; 177b9fbb7290b02de1ce621deaa2d28a5e42f2e0937Jeff Sharkey case 'G': k = ConversionSpecifier::GArg; break; 178b9fbb7290b02de1ce621deaa2d28a5e42f2e0937Jeff Sharkey case 'X': k = ConversionSpecifier::XArg; break; 17921de56a94668e0fda1b8bb4ee4f99a09b40d28fdJeff Sharkey case 'a': k = ConversionSpecifier::aArg; break; 18021de56a94668e0fda1b8bb4ee4f99a09b40d28fdJeff Sharkey case 'c': k = ConversionSpecifier::cArg; break; 18121de56a94668e0fda1b8bb4ee4f99a09b40d28fdJeff Sharkey case 'd': k = ConversionSpecifier::dArg; break; 18221de56a94668e0fda1b8bb4ee4f99a09b40d28fdJeff Sharkey case 'e': k = ConversionSpecifier::eArg; break; 183b9fbb7290b02de1ce621deaa2d28a5e42f2e0937Jeff Sharkey case 'f': k = ConversionSpecifier::fArg; break; 18421de56a94668e0fda1b8bb4ee4f99a09b40d28fdJeff Sharkey case 'g': k = ConversionSpecifier::gArg; break; 18521de56a94668e0fda1b8bb4ee4f99a09b40d28fdJeff Sharkey case 'i': k = ConversionSpecifier::iArg; break; 18621de56a94668e0fda1b8bb4ee4f99a09b40d28fdJeff Sharkey case 'n': k = ConversionSpecifier::nArg; break; 18721de56a94668e0fda1b8bb4ee4f99a09b40d28fdJeff Sharkey case 'o': k = ConversionSpecifier::oArg; break; 18821de56a94668e0fda1b8bb4ee4f99a09b40d28fdJeff Sharkey case 'p': k = ConversionSpecifier::pArg; break; 18921de56a94668e0fda1b8bb4ee4f99a09b40d28fdJeff Sharkey case 's': k = ConversionSpecifier::sArg; break; 190b9fbb7290b02de1ce621deaa2d28a5e42f2e0937Jeff Sharkey case 'u': k = ConversionSpecifier::uArg; break; 191b9fbb7290b02de1ce621deaa2d28a5e42f2e0937Jeff Sharkey case 'x': k = ConversionSpecifier::xArg; break; 192b9fbb7290b02de1ce621deaa2d28a5e42f2e0937Jeff Sharkey // POSIX specific. 193b9fbb7290b02de1ce621deaa2d28a5e42f2e0937Jeff Sharkey case 'C': k = ConversionSpecifier::CArg; break; 19421de56a94668e0fda1b8bb4ee4f99a09b40d28fdJeff Sharkey case 'S': k = ConversionSpecifier::SArg; break; 19521de56a94668e0fda1b8bb4ee4f99a09b40d28fdJeff Sharkey // Objective-C. 19621de56a94668e0fda1b8bb4ee4f99a09b40d28fdJeff Sharkey case '@': k = ConversionSpecifier::ObjCObjArg; break; 19721de56a94668e0fda1b8bb4ee4f99a09b40d28fdJeff Sharkey // Glibc specific. 19821de56a94668e0fda1b8bb4ee4f99a09b40d28fdJeff Sharkey case 'm': k = ConversionSpecifier::PrintErrno; break; 19921de56a94668e0fda1b8bb4ee4f99a09b40d28fdJeff Sharkey } 20021de56a94668e0fda1b8bb4ee4f99a09b40d28fdJeff Sharkey PrintfConversionSpecifier CS(conversionPosition, k); 20121de56a94668e0fda1b8bb4ee4f99a09b40d28fdJeff Sharkey FS.setConversionSpecifier(CS); 20221de56a94668e0fda1b8bb4ee4f99a09b40d28fdJeff Sharkey if (CS.consumesDataArgument() && !FS.usesPositionalArg()) 20321de56a94668e0fda1b8bb4ee4f99a09b40d28fdJeff Sharkey FS.setArgIndex(argIndex++); 20421de56a94668e0fda1b8bb4ee4f99a09b40d28fdJeff Sharkey 205e8c00d8ed477e199b7f8d1b1e2f37e9cf8593372Jeff Sharkey if (k == ConversionSpecifier::InvalidSpecifier) { 2069352c383e95c3e1facd8a7a2d49ff488fb7bbcafJeff Sharkey // Assume the conversion takes one argument. 207e8c00d8ed477e199b7f8d1b1e2f37e9cf8593372Jeff Sharkey return !H.HandleInvalidPrintfConversionSpecifier(FS, Start, I - Start); 208e8c00d8ed477e199b7f8d1b1e2f37e9cf8593372Jeff Sharkey } 209aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey return PrintfSpecifierResult(Start, FS); 210e8c00d8ed477e199b7f8d1b1e2f37e9cf8593372Jeff Sharkey} 211e8c00d8ed477e199b7f8d1b1e2f37e9cf8593372Jeff Sharkey 212e8c00d8ed477e199b7f8d1b1e2f37e9cf8593372Jeff Sharkeybool clang::analyze_format_string::ParsePrintfString(FormatStringHandler &H, 213e8c00d8ed477e199b7f8d1b1e2f37e9cf8593372Jeff Sharkey const char *I, 214e8c00d8ed477e199b7f8d1b1e2f37e9cf8593372Jeff Sharkey const char *E) { 215e8c00d8ed477e199b7f8d1b1e2f37e9cf8593372Jeff Sharkey 216b7e1255d5c8d9e4fa8dd389afb9f5aab35434df3Jeff Sharkey unsigned argIndex = 0; 217aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey 218aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey // Keep looking for a format specifier until we have exhausted the string. 219e8c00d8ed477e199b7f8d1b1e2f37e9cf8593372Jeff Sharkey while (I != E) { 220aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey const PrintfSpecifierResult &FSR = ParsePrintfSpecifier(H, I, E, argIndex); 221aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey // Did a fail-stop error of any kind occur when parsing the specifier? 222aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey // If so, don't do any more processing. 223aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey if (FSR.shouldStop()) 224aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey return true;; 225b7e1255d5c8d9e4fa8dd389afb9f5aab35434df3Jeff Sharkey // Did we exhaust the string or encounter an error that 226b7e1255d5c8d9e4fa8dd389afb9f5aab35434df3Jeff Sharkey // we can recover from? 227b7e1255d5c8d9e4fa8dd389afb9f5aab35434df3Jeff Sharkey if (!FSR.hasValue()) 228b7e1255d5c8d9e4fa8dd389afb9f5aab35434df3Jeff Sharkey continue; 229b7e1255d5c8d9e4fa8dd389afb9f5aab35434df3Jeff Sharkey // We have a format specifier. Pass it to the callback. 230b7e1255d5c8d9e4fa8dd389afb9f5aab35434df3Jeff Sharkey if (!H.HandlePrintfSpecifier(FSR.getValue(), FSR.getStart(), 231b7e1255d5c8d9e4fa8dd389afb9f5aab35434df3Jeff Sharkey I - FSR.getStart())) 232b7e1255d5c8d9e4fa8dd389afb9f5aab35434df3Jeff Sharkey return true; 233b7e1255d5c8d9e4fa8dd389afb9f5aab35434df3Jeff Sharkey } 234b7e1255d5c8d9e4fa8dd389afb9f5aab35434df3Jeff Sharkey assert(I == E && "Format string not exhausted"); 235b7e1255d5c8d9e4fa8dd389afb9f5aab35434df3Jeff Sharkey return false; 236b7e1255d5c8d9e4fa8dd389afb9f5aab35434df3Jeff Sharkey} 237b7e1255d5c8d9e4fa8dd389afb9f5aab35434df3Jeff Sharkey 238b7e1255d5c8d9e4fa8dd389afb9f5aab35434df3Jeff Sharkey//===----------------------------------------------------------------------===// 239b7e1255d5c8d9e4fa8dd389afb9f5aab35434df3Jeff Sharkey// Methods on ConversionSpecifier. 240b7e1255d5c8d9e4fa8dd389afb9f5aab35434df3Jeff Sharkey//===----------------------------------------------------------------------===// 241b7e1255d5c8d9e4fa8dd389afb9f5aab35434df3Jeff Sharkeyconst char *ConversionSpecifier::toString() const { 242b7e1255d5c8d9e4fa8dd389afb9f5aab35434df3Jeff Sharkey switch (kind) { 243b7e1255d5c8d9e4fa8dd389afb9f5aab35434df3Jeff Sharkey case dArg: return "d"; 244b7e1255d5c8d9e4fa8dd389afb9f5aab35434df3Jeff Sharkey case iArg: return "i"; 245b7e1255d5c8d9e4fa8dd389afb9f5aab35434df3Jeff Sharkey case oArg: return "o"; 246b7e1255d5c8d9e4fa8dd389afb9f5aab35434df3Jeff Sharkey case uArg: return "u"; 247b7e1255d5c8d9e4fa8dd389afb9f5aab35434df3Jeff Sharkey case xArg: return "x"; 248b7e1255d5c8d9e4fa8dd389afb9f5aab35434df3Jeff Sharkey case XArg: return "X"; 249b7e1255d5c8d9e4fa8dd389afb9f5aab35434df3Jeff Sharkey case fArg: return "f"; 250b7e1255d5c8d9e4fa8dd389afb9f5aab35434df3Jeff Sharkey case FArg: return "F"; 251b7e1255d5c8d9e4fa8dd389afb9f5aab35434df3Jeff Sharkey case eArg: return "e"; 252aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey case EArg: return "E"; 253ae9b51bfa313c51a31af30875a71255d7b6d2e61Jeff Sharkey case gArg: return "g"; 254aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey case GArg: return "G"; 255aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey case aArg: return "a"; 256ae9b51bfa313c51a31af30875a71255d7b6d2e61Jeff Sharkey case AArg: return "A"; 257ae9b51bfa313c51a31af30875a71255d7b6d2e61Jeff Sharkey case cArg: return "c"; 258aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey case sArg: return "s"; 259aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey case pArg: return "p"; 260e8c00d8ed477e199b7f8d1b1e2f37e9cf8593372Jeff Sharkey case nArg: return "n"; 2619352c383e95c3e1facd8a7a2d49ff488fb7bbcafJeff Sharkey case PercentArg: return "%"; 2629352c383e95c3e1facd8a7a2d49ff488fb7bbcafJeff Sharkey case ScanListArg: return "["; 2639352c383e95c3e1facd8a7a2d49ff488fb7bbcafJeff Sharkey case InvalidSpecifier: return NULL; 264e8c00d8ed477e199b7f8d1b1e2f37e9cf8593372Jeff Sharkey 265e8c00d8ed477e199b7f8d1b1e2f37e9cf8593372Jeff Sharkey // MacOS X unicode extensions. 266e8c00d8ed477e199b7f8d1b1e2f37e9cf8593372Jeff Sharkey case CArg: return "C"; 267e8c00d8ed477e199b7f8d1b1e2f37e9cf8593372Jeff Sharkey case SArg: return "S"; 268e8c00d8ed477e199b7f8d1b1e2f37e9cf8593372Jeff Sharkey 269e8c00d8ed477e199b7f8d1b1e2f37e9cf8593372Jeff Sharkey // Objective-C specific specifiers. 2709352c383e95c3e1facd8a7a2d49ff488fb7bbcafJeff Sharkey case ObjCObjArg: return "@"; 2719352c383e95c3e1facd8a7a2d49ff488fb7bbcafJeff Sharkey 272e8c00d8ed477e199b7f8d1b1e2f37e9cf8593372Jeff Sharkey // GlibC specific specifiers. 273e8c00d8ed477e199b7f8d1b1e2f37e9cf8593372Jeff Sharkey case PrintErrno: return "m"; 274e8c00d8ed477e199b7f8d1b1e2f37e9cf8593372Jeff Sharkey } 275e8c00d8ed477e199b7f8d1b1e2f37e9cf8593372Jeff Sharkey return NULL; 276ae9b51bfa313c51a31af30875a71255d7b6d2e61Jeff Sharkey} 277ae9b51bfa313c51a31af30875a71255d7b6d2e61Jeff Sharkey 278e8c00d8ed477e199b7f8d1b1e2f37e9cf8593372Jeff Sharkey//===----------------------------------------------------------------------===// 279e8c00d8ed477e199b7f8d1b1e2f37e9cf8593372Jeff Sharkey// Methods on PrintfSpecifier. 280e8c00d8ed477e199b7f8d1b1e2f37e9cf8593372Jeff Sharkey//===----------------------------------------------------------------------===// 281e8c00d8ed477e199b7f8d1b1e2f37e9cf8593372Jeff Sharkey 282e8c00d8ed477e199b7f8d1b1e2f37e9cf8593372Jeff SharkeyArgTypeResult PrintfSpecifier::getArgType(ASTContext &Ctx) const { 283e8c00d8ed477e199b7f8d1b1e2f37e9cf8593372Jeff Sharkey const PrintfConversionSpecifier &CS = getConversionSpecifier(); 28437ed78e504ef3666dd5fce15ff4994f151c44fcdJeff Sharkey 28537ed78e504ef3666dd5fce15ff4994f151c44fcdJeff Sharkey if (!CS.consumesDataArgument()) 286e8c00d8ed477e199b7f8d1b1e2f37e9cf8593372Jeff Sharkey return ArgTypeResult::Invalid(); 287e8c00d8ed477e199b7f8d1b1e2f37e9cf8593372Jeff Sharkey 288e8c00d8ed477e199b7f8d1b1e2f37e9cf8593372Jeff Sharkey if (CS.getKind() == ConversionSpecifier::cArg) 289e8c00d8ed477e199b7f8d1b1e2f37e9cf8593372Jeff Sharkey switch (LM.getKind()) { 290e8c00d8ed477e199b7f8d1b1e2f37e9cf8593372Jeff Sharkey case LengthModifier::None: return Ctx.IntTy; 291e8c00d8ed477e199b7f8d1b1e2f37e9cf8593372Jeff Sharkey case LengthModifier::AsLong: return ArgTypeResult::WIntTy; 292aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey default: 293ae9b51bfa313c51a31af30875a71255d7b6d2e61Jeff Sharkey return ArgTypeResult::Invalid(); 294ae9b51bfa313c51a31af30875a71255d7b6d2e61Jeff Sharkey } 295ae9b51bfa313c51a31af30875a71255d7b6d2e61Jeff Sharkey 296aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey if (CS.isIntArg()) 297aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey switch (LM.getKind()) { 298aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey case LengthModifier::AsLongDouble: 2999352c383e95c3e1facd8a7a2d49ff488fb7bbcafJeff Sharkey return ArgTypeResult::Invalid(); 3009352c383e95c3e1facd8a7a2d49ff488fb7bbcafJeff Sharkey case LengthModifier::None: return Ctx.IntTy; 301aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey case LengthModifier::AsChar: return Ctx.SignedCharTy; 302ae9b51bfa313c51a31af30875a71255d7b6d2e61Jeff Sharkey case LengthModifier::AsShort: return Ctx.ShortTy; 303e8c00d8ed477e199b7f8d1b1e2f37e9cf8593372Jeff Sharkey case LengthModifier::AsLong: return Ctx.LongTy; 304e8c00d8ed477e199b7f8d1b1e2f37e9cf8593372Jeff Sharkey case LengthModifier::AsLongLong: return Ctx.LongLongTy; 305e8c00d8ed477e199b7f8d1b1e2f37e9cf8593372Jeff Sharkey case LengthModifier::AsIntMax: 306aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey // FIXME: Return unknown for now. 307ae9b51bfa313c51a31af30875a71255d7b6d2e61Jeff Sharkey return ArgTypeResult(); 308ae9b51bfa313c51a31af30875a71255d7b6d2e61Jeff Sharkey case LengthModifier::AsSizeT: return Ctx.getSizeType(); 309aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey case LengthModifier::AsPtrDiff: return Ctx.getPointerDiffType(); 310aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey } 311e8c00d8ed477e199b7f8d1b1e2f37e9cf8593372Jeff Sharkey 312e8c00d8ed477e199b7f8d1b1e2f37e9cf8593372Jeff Sharkey if (CS.isUIntArg()) 313e8c00d8ed477e199b7f8d1b1e2f37e9cf8593372Jeff Sharkey switch (LM.getKind()) { 314e8c00d8ed477e199b7f8d1b1e2f37e9cf8593372Jeff Sharkey case LengthModifier::AsLongDouble: 315e8c00d8ed477e199b7f8d1b1e2f37e9cf8593372Jeff Sharkey return ArgTypeResult::Invalid(); 316e8c00d8ed477e199b7f8d1b1e2f37e9cf8593372Jeff Sharkey case LengthModifier::None: return Ctx.UnsignedIntTy; 317e8c00d8ed477e199b7f8d1b1e2f37e9cf8593372Jeff Sharkey case LengthModifier::AsChar: return Ctx.UnsignedCharTy; 3189352c383e95c3e1facd8a7a2d49ff488fb7bbcafJeff Sharkey case LengthModifier::AsShort: return Ctx.UnsignedShortTy; 3199352c383e95c3e1facd8a7a2d49ff488fb7bbcafJeff Sharkey case LengthModifier::AsLong: return Ctx.UnsignedLongTy; 3203b945405cf96eae8b882f87934222a453718a559Jeff Sharkey case LengthModifier::AsLongLong: return Ctx.UnsignedLongLongTy; 3213b945405cf96eae8b882f87934222a453718a559Jeff Sharkey case LengthModifier::AsIntMax: 3229352c383e95c3e1facd8a7a2d49ff488fb7bbcafJeff Sharkey // FIXME: Return unknown for now. 3239352c383e95c3e1facd8a7a2d49ff488fb7bbcafJeff Sharkey return ArgTypeResult(); 3249352c383e95c3e1facd8a7a2d49ff488fb7bbcafJeff Sharkey case LengthModifier::AsSizeT: 3259352c383e95c3e1facd8a7a2d49ff488fb7bbcafJeff Sharkey // FIXME: How to get the corresponding unsigned 3269352c383e95c3e1facd8a7a2d49ff488fb7bbcafJeff Sharkey // version of size_t? 3279352c383e95c3e1facd8a7a2d49ff488fb7bbcafJeff Sharkey return ArgTypeResult(); 3289352c383e95c3e1facd8a7a2d49ff488fb7bbcafJeff Sharkey case LengthModifier::AsPtrDiff: 3299352c383e95c3e1facd8a7a2d49ff488fb7bbcafJeff Sharkey // FIXME: How to get the corresponding unsigned 330aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey // version of ptrdiff_t? 331ae9b51bfa313c51a31af30875a71255d7b6d2e61Jeff Sharkey return ArgTypeResult(); 332e8c00d8ed477e199b7f8d1b1e2f37e9cf8593372Jeff Sharkey } 333e8c00d8ed477e199b7f8d1b1e2f37e9cf8593372Jeff Sharkey 334e8c00d8ed477e199b7f8d1b1e2f37e9cf8593372Jeff Sharkey if (CS.isDoubleArg()) { 335e8c00d8ed477e199b7f8d1b1e2f37e9cf8593372Jeff Sharkey if (LM.getKind() == LengthModifier::AsLongDouble) 336e8c00d8ed477e199b7f8d1b1e2f37e9cf8593372Jeff Sharkey return Ctx.LongDoubleTy; 337e8c00d8ed477e199b7f8d1b1e2f37e9cf8593372Jeff Sharkey return Ctx.DoubleTy; 338e8c00d8ed477e199b7f8d1b1e2f37e9cf8593372Jeff Sharkey } 339e8c00d8ed477e199b7f8d1b1e2f37e9cf8593372Jeff Sharkey 340e8c00d8ed477e199b7f8d1b1e2f37e9cf8593372Jeff Sharkey switch (CS.getKind()) { 341e8c00d8ed477e199b7f8d1b1e2f37e9cf8593372Jeff Sharkey case ConversionSpecifier::sArg: 342e8c00d8ed477e199b7f8d1b1e2f37e9cf8593372Jeff Sharkey return ArgTypeResult(LM.getKind() == LengthModifier::AsWideChar ? 343e8c00d8ed477e199b7f8d1b1e2f37e9cf8593372Jeff Sharkey ArgTypeResult::WCStrTy : ArgTypeResult::CStrTy); 344aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey case ConversionSpecifier::SArg: 345ae9b51bfa313c51a31af30875a71255d7b6d2e61Jeff Sharkey // FIXME: This appears to be Mac OS X specific. 346ae9b51bfa313c51a31af30875a71255d7b6d2e61Jeff Sharkey return ArgTypeResult::WCStrTy; 347ae9b51bfa313c51a31af30875a71255d7b6d2e61Jeff Sharkey case ConversionSpecifier::CArg: 348aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey return Ctx.WCharTy; 3494ec973925fc2cd18f9ec0d0ca5af588564fded27Jeff Sharkey case ConversionSpecifier::pArg: 3504ec973925fc2cd18f9ec0d0ca5af588564fded27Jeff Sharkey return ArgTypeResult::CPointerTy; 3514ec973925fc2cd18f9ec0d0ca5af588564fded27Jeff Sharkey default: 3524ec973925fc2cd18f9ec0d0ca5af588564fded27Jeff Sharkey break; 3534ec973925fc2cd18f9ec0d0ca5af588564fded27Jeff Sharkey } 3544ec973925fc2cd18f9ec0d0ca5af588564fded27Jeff Sharkey 3554ec973925fc2cd18f9ec0d0ca5af588564fded27Jeff Sharkey // FIXME: Handle other cases. 3564ec973925fc2cd18f9ec0d0ca5af588564fded27Jeff Sharkey return ArgTypeResult(); 357aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey} 358e8c00d8ed477e199b7f8d1b1e2f37e9cf8593372Jeff Sharkey 359e8c00d8ed477e199b7f8d1b1e2f37e9cf8593372Jeff Sharkeybool PrintfSpecifier::fixType(QualType QT) { 360e8c00d8ed477e199b7f8d1b1e2f37e9cf8593372Jeff Sharkey // Handle strings first (char *, wchar_t *) 361e8c00d8ed477e199b7f8d1b1e2f37e9cf8593372Jeff Sharkey if (QT->isPointerType() && (QT->getPointeeType()->isAnyCharacterType())) { 362e8c00d8ed477e199b7f8d1b1e2f37e9cf8593372Jeff Sharkey CS.setKind(ConversionSpecifier::sArg); 363e8c00d8ed477e199b7f8d1b1e2f37e9cf8593372Jeff Sharkey 364e8c00d8ed477e199b7f8d1b1e2f37e9cf8593372Jeff Sharkey // Disable irrelevant flags 365e8c00d8ed477e199b7f8d1b1e2f37e9cf8593372Jeff Sharkey HasAlternativeForm = 0; 366e8c00d8ed477e199b7f8d1b1e2f37e9cf8593372Jeff Sharkey HasLeadingZeroes = 0; 3679352c383e95c3e1facd8a7a2d49ff488fb7bbcafJeff Sharkey 3689352c383e95c3e1facd8a7a2d49ff488fb7bbcafJeff Sharkey // Set the long length modifier for wide characters 3699352c383e95c3e1facd8a7a2d49ff488fb7bbcafJeff Sharkey if (QT->getPointeeType()->isWideCharType()) 3709352c383e95c3e1facd8a7a2d49ff488fb7bbcafJeff Sharkey LM.setKind(LengthModifier::AsWideChar); 3719352c383e95c3e1facd8a7a2d49ff488fb7bbcafJeff Sharkey 3729352c383e95c3e1facd8a7a2d49ff488fb7bbcafJeff Sharkey return true; 3739352c383e95c3e1facd8a7a2d49ff488fb7bbcafJeff Sharkey } 3749352c383e95c3e1facd8a7a2d49ff488fb7bbcafJeff Sharkey 3759352c383e95c3e1facd8a7a2d49ff488fb7bbcafJeff Sharkey // We can only work with builtin types. 3769352c383e95c3e1facd8a7a2d49ff488fb7bbcafJeff Sharkey if (!QT->isBuiltinType()) 3779352c383e95c3e1facd8a7a2d49ff488fb7bbcafJeff Sharkey return false; 3789352c383e95c3e1facd8a7a2d49ff488fb7bbcafJeff Sharkey 3799352c383e95c3e1facd8a7a2d49ff488fb7bbcafJeff Sharkey // Everything else should be a base type 3809352c383e95c3e1facd8a7a2d49ff488fb7bbcafJeff Sharkey const BuiltinType *BT = QT->getAs<BuiltinType>(); 381aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey 3823e1189b3590aefb65a2af720ae2ba959bbd4188dJeff Sharkey // Set length modifier 383e8c00d8ed477e199b7f8d1b1e2f37e9cf8593372Jeff Sharkey switch (BT->getKind()) { 384e8c00d8ed477e199b7f8d1b1e2f37e9cf8593372Jeff Sharkey default: 385e8c00d8ed477e199b7f8d1b1e2f37e9cf8593372Jeff Sharkey // The rest of the conversions are either optional or for non-builtin types 386e8c00d8ed477e199b7f8d1b1e2f37e9cf8593372Jeff Sharkey LM.setKind(LengthModifier::None); 387e8c00d8ed477e199b7f8d1b1e2f37e9cf8593372Jeff Sharkey break; 388e8c00d8ed477e199b7f8d1b1e2f37e9cf8593372Jeff Sharkey 389e8c00d8ed477e199b7f8d1b1e2f37e9cf8593372Jeff Sharkey case BuiltinType::Char_U: 390aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey case BuiltinType::UChar: 391aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey case BuiltinType::Char_S: 3923e1189b3590aefb65a2af720ae2ba959bbd4188dJeff Sharkey case BuiltinType::SChar: 393ae9b51bfa313c51a31af30875a71255d7b6d2e61Jeff Sharkey LM.setKind(LengthModifier::AsChar); 394aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey break; 395aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey 396aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey case BuiltinType::Short: 397aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey case BuiltinType::UShort: 398e8c00d8ed477e199b7f8d1b1e2f37e9cf8593372Jeff Sharkey LM.setKind(LengthModifier::AsShort); 399e8c00d8ed477e199b7f8d1b1e2f37e9cf8593372Jeff Sharkey break; 400e8c00d8ed477e199b7f8d1b1e2f37e9cf8593372Jeff Sharkey 401e8c00d8ed477e199b7f8d1b1e2f37e9cf8593372Jeff Sharkey case BuiltinType::WChar_S: 402aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey case BuiltinType::WChar_U: 403ae9b51bfa313c51a31af30875a71255d7b6d2e61Jeff Sharkey case BuiltinType::Long: 404ae9b51bfa313c51a31af30875a71255d7b6d2e61Jeff Sharkey case BuiltinType::ULong: 405aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey LM.setKind(LengthModifier::AsLong); 406aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey break; 407ae9b51bfa313c51a31af30875a71255d7b6d2e61Jeff Sharkey 408aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey case BuiltinType::LongLong: 409aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey case BuiltinType::ULongLong: 410aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey LM.setKind(LengthModifier::AsLongLong); 411aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey break; 412aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey 413aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey case BuiltinType::LongDouble: 414aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey LM.setKind(LengthModifier::AsLongDouble); 415aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey break; 416aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey } 417e8c00d8ed477e199b7f8d1b1e2f37e9cf8593372Jeff Sharkey 418e8c00d8ed477e199b7f8d1b1e2f37e9cf8593372Jeff Sharkey // Set conversion specifier and disable any flags which do not apply to it. 4199352c383e95c3e1facd8a7a2d49ff488fb7bbcafJeff Sharkey // Let typedefs to char fall through to int, as %c is silly for uint8_t. 420e8c00d8ed477e199b7f8d1b1e2f37e9cf8593372Jeff Sharkey if (isa<TypedefType>(QT) && QT->isAnyCharacterType()) { 4219352c383e95c3e1facd8a7a2d49ff488fb7bbcafJeff Sharkey CS.setKind(ConversionSpecifier::cArg); 4229352c383e95c3e1facd8a7a2d49ff488fb7bbcafJeff Sharkey LM.setKind(LengthModifier::None); 4239352c383e95c3e1facd8a7a2d49ff488fb7bbcafJeff Sharkey Precision.setHowSpecified(OptionalAmount::NotSpecified); 424e8c00d8ed477e199b7f8d1b1e2f37e9cf8593372Jeff Sharkey HasAlternativeForm = 0; 4259352c383e95c3e1facd8a7a2d49ff488fb7bbcafJeff Sharkey HasLeadingZeroes = 0; 4269352c383e95c3e1facd8a7a2d49ff488fb7bbcafJeff Sharkey HasPlusPrefix = 0; 427aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey } 428e8c00d8ed477e199b7f8d1b1e2f37e9cf8593372Jeff Sharkey // Test for Floating type first as LongDouble can pass isUnsignedIntegerType 429aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey else if (QT->isRealFloatingType()) { 430aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey CS.setKind(ConversionSpecifier::fArg); 4313b945405cf96eae8b882f87934222a453718a559Jeff Sharkey } 432aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey else if (QT->isPointerType()) { 433aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey CS.setKind(ConversionSpecifier::pArg); 434aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey Precision.setHowSpecified(OptionalAmount::NotSpecified); 435aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey HasAlternativeForm = 0; 436e8c00d8ed477e199b7f8d1b1e2f37e9cf8593372Jeff Sharkey HasLeadingZeroes = 0; 437aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey HasPlusPrefix = 0; 438aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey } 439e8c00d8ed477e199b7f8d1b1e2f37e9cf8593372Jeff Sharkey else if (QT->isSignedIntegerType()) { 440aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey CS.setKind(ConversionSpecifier::dArg); 441aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey HasAlternativeForm = 0; 442e8c00d8ed477e199b7f8d1b1e2f37e9cf8593372Jeff Sharkey } 443e8c00d8ed477e199b7f8d1b1e2f37e9cf8593372Jeff Sharkey else if (QT->isUnsignedIntegerType()) { 444e8c00d8ed477e199b7f8d1b1e2f37e9cf8593372Jeff Sharkey CS.setKind(ConversionSpecifier::uArg); 445e8c00d8ed477e199b7f8d1b1e2f37e9cf8593372Jeff Sharkey HasAlternativeForm = 0; 446e8c00d8ed477e199b7f8d1b1e2f37e9cf8593372Jeff Sharkey HasPlusPrefix = 0; 447e8c00d8ed477e199b7f8d1b1e2f37e9cf8593372Jeff Sharkey } 4489352c383e95c3e1facd8a7a2d49ff488fb7bbcafJeff Sharkey else { 4499352c383e95c3e1facd8a7a2d49ff488fb7bbcafJeff Sharkey return false; 4509352c383e95c3e1facd8a7a2d49ff488fb7bbcafJeff Sharkey } 451aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey 452e8c00d8ed477e199b7f8d1b1e2f37e9cf8593372Jeff Sharkey return true; 453aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey} 454aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey 4553b945405cf96eae8b882f87934222a453718a559Jeff Sharkeyvoid PrintfSpecifier::toString(llvm::raw_ostream &os) const { 456ae9b51bfa313c51a31af30875a71255d7b6d2e61Jeff Sharkey // Whilst some features have no defined order, we are using the order 457aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey // appearing in the C99 standard (ISO/IEC 9899:1999 (E) 7.19.6.1) 458aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey os << "%"; 459aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey 460e8c00d8ed477e199b7f8d1b1e2f37e9cf8593372Jeff Sharkey // Positional args 461e8c00d8ed477e199b7f8d1b1e2f37e9cf8593372Jeff Sharkey if (usesPositionalArg()) { 462aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey os << getPositionalArgIndex() << "$"; 463aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey } 464aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey 465ae9b51bfa313c51a31af30875a71255d7b6d2e61Jeff Sharkey // Conversion flags 466ae9b51bfa313c51a31af30875a71255d7b6d2e61Jeff Sharkey if (IsLeftJustified) os << "-"; 467ae9b51bfa313c51a31af30875a71255d7b6d2e61Jeff Sharkey if (HasPlusPrefix) os << "+"; 468ae9b51bfa313c51a31af30875a71255d7b6d2e61Jeff Sharkey if (HasSpacePrefix) os << " "; 469ae9b51bfa313c51a31af30875a71255d7b6d2e61Jeff Sharkey if (HasAlternativeForm) os << "#"; 470ae9b51bfa313c51a31af30875a71255d7b6d2e61Jeff Sharkey if (HasLeadingZeroes) os << "0"; 471ae9b51bfa313c51a31af30875a71255d7b6d2e61Jeff Sharkey 472ae9b51bfa313c51a31af30875a71255d7b6d2e61Jeff Sharkey // Minimum field width 473ae9b51bfa313c51a31af30875a71255d7b6d2e61Jeff Sharkey FieldWidth.toString(os); 474aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey // Precision 475ae9b51bfa313c51a31af30875a71255d7b6d2e61Jeff Sharkey Precision.toString(os); 476ae9b51bfa313c51a31af30875a71255d7b6d2e61Jeff Sharkey // Length modifier 477aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey os << LM.toString(); 478aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey // Conversion specifier 479a61dc8e03e6e863005b3a4629ca8f3801d33d3c4Jeff Sharkey os << CS.toString(); 480ae9b51bfa313c51a31af30875a71255d7b6d2e61Jeff Sharkey} 481ae9b51bfa313c51a31af30875a71255d7b6d2e61Jeff Sharkey 482ae9b51bfa313c51a31af30875a71255d7b6d2e61Jeff Sharkeybool PrintfSpecifier::hasValidPlusPrefix() const { 4833e1189b3590aefb65a2af720ae2ba959bbd4188dJeff Sharkey if (!HasPlusPrefix) 4843e1189b3590aefb65a2af720ae2ba959bbd4188dJeff Sharkey return true; 4853e1189b3590aefb65a2af720ae2ba959bbd4188dJeff Sharkey 486aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey // The plus prefix only makes sense for signed conversions 487b9fbb7290b02de1ce621deaa2d28a5e42f2e0937Jeff Sharkey switch (CS.getKind()) { 488b9fbb7290b02de1ce621deaa2d28a5e42f2e0937Jeff Sharkey case ConversionSpecifier::dArg: 489ae9b51bfa313c51a31af30875a71255d7b6d2e61Jeff Sharkey case ConversionSpecifier::iArg: 490aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey case ConversionSpecifier::fArg: 491b9fbb7290b02de1ce621deaa2d28a5e42f2e0937Jeff Sharkey case ConversionSpecifier::FArg: 492b9fbb7290b02de1ce621deaa2d28a5e42f2e0937Jeff Sharkey case ConversionSpecifier::eArg: 4934ec973925fc2cd18f9ec0d0ca5af588564fded27Jeff Sharkey case ConversionSpecifier::EArg: 4944ec973925fc2cd18f9ec0d0ca5af588564fded27Jeff Sharkey case ConversionSpecifier::gArg: 4954ec973925fc2cd18f9ec0d0ca5af588564fded27Jeff Sharkey case ConversionSpecifier::GArg: 4964ec973925fc2cd18f9ec0d0ca5af588564fded27Jeff Sharkey case ConversionSpecifier::aArg: 4974ec973925fc2cd18f9ec0d0ca5af588564fded27Jeff Sharkey case ConversionSpecifier::AArg: 4984ec973925fc2cd18f9ec0d0ca5af588564fded27Jeff Sharkey return true; 499aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey 500aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey default: 501aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey return false; 502aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey } 503aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey} 504aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey 505aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkeybool PrintfSpecifier::hasValidAlternativeForm() const { 506aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey if (!HasAlternativeForm) 507aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey return true; 508ae9b51bfa313c51a31af30875a71255d7b6d2e61Jeff Sharkey 509ae9b51bfa313c51a31af30875a71255d7b6d2e61Jeff Sharkey // Alternate form flag only valid with the oxXaAeEfFgG conversions 510ae9b51bfa313c51a31af30875a71255d7b6d2e61Jeff Sharkey switch (CS.getKind()) { 511ae9b51bfa313c51a31af30875a71255d7b6d2e61Jeff Sharkey case ConversionSpecifier::oArg: 512ae9b51bfa313c51a31af30875a71255d7b6d2e61Jeff Sharkey case ConversionSpecifier::xArg: 513aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey case ConversionSpecifier::XArg: 514aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey case ConversionSpecifier::aArg: 515aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey case ConversionSpecifier::AArg: 516aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey case ConversionSpecifier::eArg: 517a61dc8e03e6e863005b3a4629ca8f3801d33d3c4Jeff Sharkey case ConversionSpecifier::EArg: 518a61dc8e03e6e863005b3a4629ca8f3801d33d3c4Jeff Sharkey case ConversionSpecifier::fArg: 519aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey case ConversionSpecifier::FArg: 520b9fbb7290b02de1ce621deaa2d28a5e42f2e0937Jeff Sharkey case ConversionSpecifier::gArg: 521b9fbb7290b02de1ce621deaa2d28a5e42f2e0937Jeff Sharkey case ConversionSpecifier::GArg: 522ae9b51bfa313c51a31af30875a71255d7b6d2e61Jeff Sharkey return true; 523aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey 524aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey default: 525aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey return false; 526aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey } 527aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey} 528aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey 529aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkeybool PrintfSpecifier::hasValidLeadingZeros() const { 530aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey if (!HasLeadingZeroes) 531aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey return true; 532ae9b51bfa313c51a31af30875a71255d7b6d2e61Jeff Sharkey 53321de56a94668e0fda1b8bb4ee4f99a09b40d28fdJeff Sharkey // Leading zeroes flag only valid with the diouxXaAeEfFgG conversions 53421de56a94668e0fda1b8bb4ee4f99a09b40d28fdJeff Sharkey switch (CS.getKind()) { 53521de56a94668e0fda1b8bb4ee4f99a09b40d28fdJeff Sharkey case ConversionSpecifier::dArg: 53621de56a94668e0fda1b8bb4ee4f99a09b40d28fdJeff Sharkey case ConversionSpecifier::iArg: 53721de56a94668e0fda1b8bb4ee4f99a09b40d28fdJeff Sharkey case ConversionSpecifier::oArg: 538b9fbb7290b02de1ce621deaa2d28a5e42f2e0937Jeff Sharkey case ConversionSpecifier::uArg: 53921de56a94668e0fda1b8bb4ee4f99a09b40d28fdJeff Sharkey case ConversionSpecifier::xArg: 54021de56a94668e0fda1b8bb4ee4f99a09b40d28fdJeff Sharkey case ConversionSpecifier::XArg: 54121de56a94668e0fda1b8bb4ee4f99a09b40d28fdJeff Sharkey case ConversionSpecifier::aArg: 542b9fbb7290b02de1ce621deaa2d28a5e42f2e0937Jeff Sharkey case ConversionSpecifier::AArg: 54321de56a94668e0fda1b8bb4ee4f99a09b40d28fdJeff Sharkey case ConversionSpecifier::eArg: 54421de56a94668e0fda1b8bb4ee4f99a09b40d28fdJeff Sharkey case ConversionSpecifier::EArg: 54521de56a94668e0fda1b8bb4ee4f99a09b40d28fdJeff Sharkey case ConversionSpecifier::fArg: 54621de56a94668e0fda1b8bb4ee4f99a09b40d28fdJeff Sharkey case ConversionSpecifier::FArg: 54721de56a94668e0fda1b8bb4ee4f99a09b40d28fdJeff Sharkey case ConversionSpecifier::gArg: 548b9fbb7290b02de1ce621deaa2d28a5e42f2e0937Jeff Sharkey case ConversionSpecifier::GArg: 549b9fbb7290b02de1ce621deaa2d28a5e42f2e0937Jeff Sharkey return true; 55021de56a94668e0fda1b8bb4ee4f99a09b40d28fdJeff Sharkey 551b9fbb7290b02de1ce621deaa2d28a5e42f2e0937Jeff Sharkey default: 55221de56a94668e0fda1b8bb4ee4f99a09b40d28fdJeff Sharkey return false; 55321de56a94668e0fda1b8bb4ee4f99a09b40d28fdJeff Sharkey } 554b7e1255d5c8d9e4fa8dd389afb9f5aab35434df3Jeff Sharkey} 555b7e1255d5c8d9e4fa8dd389afb9f5aab35434df3Jeff Sharkey 55621de56a94668e0fda1b8bb4ee4f99a09b40d28fdJeff Sharkeybool PrintfSpecifier::hasValidSpacePrefix() const { 55721de56a94668e0fda1b8bb4ee4f99a09b40d28fdJeff Sharkey if (!HasSpacePrefix) 55821de56a94668e0fda1b8bb4ee4f99a09b40d28fdJeff Sharkey return true; 55921de56a94668e0fda1b8bb4ee4f99a09b40d28fdJeff Sharkey 56021de56a94668e0fda1b8bb4ee4f99a09b40d28fdJeff Sharkey // The space prefix only makes sense for signed conversions 56121de56a94668e0fda1b8bb4ee4f99a09b40d28fdJeff Sharkey switch (CS.getKind()) { 562b7e1255d5c8d9e4fa8dd389afb9f5aab35434df3Jeff Sharkey case ConversionSpecifier::dArg: 563b7e1255d5c8d9e4fa8dd389afb9f5aab35434df3Jeff Sharkey case ConversionSpecifier::iArg: 564b7e1255d5c8d9e4fa8dd389afb9f5aab35434df3Jeff Sharkey case ConversionSpecifier::fArg: 565b7e1255d5c8d9e4fa8dd389afb9f5aab35434df3Jeff Sharkey case ConversionSpecifier::FArg: 566b7e1255d5c8d9e4fa8dd389afb9f5aab35434df3Jeff Sharkey case ConversionSpecifier::eArg: 567b7e1255d5c8d9e4fa8dd389afb9f5aab35434df3Jeff Sharkey case ConversionSpecifier::EArg: 568b7e1255d5c8d9e4fa8dd389afb9f5aab35434df3Jeff Sharkey case ConversionSpecifier::gArg: 569b7e1255d5c8d9e4fa8dd389afb9f5aab35434df3Jeff Sharkey case ConversionSpecifier::GArg: 570b7e1255d5c8d9e4fa8dd389afb9f5aab35434df3Jeff Sharkey case ConversionSpecifier::aArg: 571b7e1255d5c8d9e4fa8dd389afb9f5aab35434df3Jeff Sharkey case ConversionSpecifier::AArg: 572b7e1255d5c8d9e4fa8dd389afb9f5aab35434df3Jeff Sharkey return true; 573b7e1255d5c8d9e4fa8dd389afb9f5aab35434df3Jeff Sharkey 574b7e1255d5c8d9e4fa8dd389afb9f5aab35434df3Jeff Sharkey default: 575b7e1255d5c8d9e4fa8dd389afb9f5aab35434df3Jeff Sharkey return false; 576b7e1255d5c8d9e4fa8dd389afb9f5aab35434df3Jeff Sharkey } 577b7e1255d5c8d9e4fa8dd389afb9f5aab35434df3Jeff Sharkey} 578b7e1255d5c8d9e4fa8dd389afb9f5aab35434df3Jeff Sharkey 579b7e1255d5c8d9e4fa8dd389afb9f5aab35434df3Jeff Sharkeybool PrintfSpecifier::hasValidLeftJustified() const { 580b7e1255d5c8d9e4fa8dd389afb9f5aab35434df3Jeff Sharkey if (!IsLeftJustified) 58121de56a94668e0fda1b8bb4ee4f99a09b40d28fdJeff Sharkey return true; 582ae9b51bfa313c51a31af30875a71255d7b6d2e61Jeff Sharkey 583ae9b51bfa313c51a31af30875a71255d7b6d2e61Jeff Sharkey // The left justified flag is valid for all conversions except n 584ae9b51bfa313c51a31af30875a71255d7b6d2e61Jeff Sharkey switch (CS.getKind()) { 585ae9b51bfa313c51a31af30875a71255d7b6d2e61Jeff Sharkey case ConversionSpecifier::nArg: 586ae9b51bfa313c51a31af30875a71255d7b6d2e61Jeff Sharkey return false; 587aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey 588aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey default: 589aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey return true; 590aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey } 591aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey} 592ae9b51bfa313c51a31af30875a71255d7b6d2e61Jeff Sharkey 593ae9b51bfa313c51a31af30875a71255d7b6d2e61Jeff Sharkeybool PrintfSpecifier::hasValidThousandsGroupingPrefix() const { 594ae9b51bfa313c51a31af30875a71255d7b6d2e61Jeff Sharkey if (!HasThousandsGrouping) 595ae9b51bfa313c51a31af30875a71255d7b6d2e61Jeff Sharkey return true; 596ae9b51bfa313c51a31af30875a71255d7b6d2e61Jeff Sharkey 597ae9b51bfa313c51a31af30875a71255d7b6d2e61Jeff Sharkey switch (CS.getKind()) { 598aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey case ConversionSpecifier::dArg: 599aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey case ConversionSpecifier::iArg: 600aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey case ConversionSpecifier::uArg: 601aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey case ConversionSpecifier::fArg: 602aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey case ConversionSpecifier::FArg: 603ae9b51bfa313c51a31af30875a71255d7b6d2e61Jeff Sharkey case ConversionSpecifier::gArg: 604ae9b51bfa313c51a31af30875a71255d7b6d2e61Jeff Sharkey case ConversionSpecifier::GArg: 605ae9b51bfa313c51a31af30875a71255d7b6d2e61Jeff Sharkey return true; 606ae9b51bfa313c51a31af30875a71255d7b6d2e61Jeff Sharkey default: 607aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey return false; 608aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey } 609aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey} 610aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey 611aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkeybool PrintfSpecifier::hasValidPrecision() const { 612aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey if (Precision.getHowSpecified() == OptionalAmount::NotSpecified) 613911d7f411f36f2279aae44c89ff1d33a29140046Jeff Sharkey return true; 614911d7f411f36f2279aae44c89ff1d33a29140046Jeff Sharkey 615911d7f411f36f2279aae44c89ff1d33a29140046Jeff Sharkey // Precision is only valid with the diouxXaAeEfFgGs conversions 616911d7f411f36f2279aae44c89ff1d33a29140046Jeff Sharkey switch (CS.getKind()) { 617911d7f411f36f2279aae44c89ff1d33a29140046Jeff Sharkey case ConversionSpecifier::dArg: 618911d7f411f36f2279aae44c89ff1d33a29140046Jeff Sharkey case ConversionSpecifier::iArg: 619aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey case ConversionSpecifier::oArg: 620911d7f411f36f2279aae44c89ff1d33a29140046Jeff Sharkey case ConversionSpecifier::uArg: 621aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey case ConversionSpecifier::xArg: 62221de56a94668e0fda1b8bb4ee4f99a09b40d28fdJeff Sharkey case ConversionSpecifier::XArg: 623911d7f411f36f2279aae44c89ff1d33a29140046Jeff Sharkey case ConversionSpecifier::aArg: 624aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey case ConversionSpecifier::AArg: 625aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey case ConversionSpecifier::eArg: 626b7e1255d5c8d9e4fa8dd389afb9f5aab35434df3Jeff Sharkey case ConversionSpecifier::EArg: 62721de56a94668e0fda1b8bb4ee4f99a09b40d28fdJeff Sharkey case ConversionSpecifier::fArg: 62821de56a94668e0fda1b8bb4ee4f99a09b40d28fdJeff Sharkey case ConversionSpecifier::FArg: 62921de56a94668e0fda1b8bb4ee4f99a09b40d28fdJeff Sharkey case ConversionSpecifier::gArg: 630e37ea6123d1aa3cd3e8804988886b1f6046d79d6Jeff Sharkey case ConversionSpecifier::GArg: 63121de56a94668e0fda1b8bb4ee4f99a09b40d28fdJeff Sharkey case ConversionSpecifier::sArg: 63221de56a94668e0fda1b8bb4ee4f99a09b40d28fdJeff Sharkey return true; 63321de56a94668e0fda1b8bb4ee4f99a09b40d28fdJeff Sharkey 63421de56a94668e0fda1b8bb4ee4f99a09b40d28fdJeff Sharkey default: 635b9fbb7290b02de1ce621deaa2d28a5e42f2e0937Jeff Sharkey return false; 636aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey } 637aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkey} 638aeb16e2435f9975b9fa1fc4b747796647a21292eJeff Sharkeybool PrintfSpecifier::hasValidFieldWidth() const { 639ae9b51bfa313c51a31af30875a71255d7b6d2e61Jeff Sharkey if (FieldWidth.getHowSpecified() == OptionalAmount::NotSpecified) 640ff17024e583b170312d82089fd358d278ce16c9aDianne Hackborn return true; 64121de56a94668e0fda1b8bb4ee4f99a09b40d28fdJeff Sharkey 642ae9b51bfa313c51a31af30875a71255d7b6d2e61Jeff Sharkey // The field width is valid for all conversions except n 643ae9b51bfa313c51a31af30875a71255d7b6d2e61Jeff Sharkey switch (CS.getKind()) { 644ae9b51bfa313c51a31af30875a71255d7b6d2e61Jeff Sharkey case ConversionSpecifier::nArg: 64521de56a94668e0fda1b8bb4ee4f99a09b40d28fdJeff Sharkey return false; 64621de56a94668e0fda1b8bb4ee4f99a09b40d28fdJeff Sharkey 64721de56a94668e0fda1b8bb4ee4f99a09b40d28fdJeff Sharkey default: 648b9fbb7290b02de1ce621deaa2d28a5e42f2e0937Jeff Sharkey return true; 649b9fbb7290b02de1ce621deaa2d28a5e42f2e0937Jeff Sharkey } 65021de56a94668e0fda1b8bb4ee4f99a09b40d28fdJeff Sharkey} 65121de56a94668e0fda1b8bb4ee4f99a09b40d28fdJeff Sharkey