PrintfFormatString.cpp revision 339b9072e26a2a0fe796dc69c4d28d964d0ec86d
1656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project//== PrintfFormatString.cpp - Analysis of printf format strings --*- C++ -*-==// 2656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project// 3656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project// The LLVM Compiler Infrastructure 4656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project// 5656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project// This file is distributed under the University of Illinois Open Source 6656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project// License. See LICENSE.TXT for details. 7656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project// 8656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project//===----------------------------------------------------------------------===// 9656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project// 10656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project// Handling of format string in printf and friends. The structure of format 11656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project// strings for fprintf() are described in C99 7.19.6.1. 12656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project// 13656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project//===----------------------------------------------------------------------===// 14656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 15656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#include "clang/Analysis/Analyses/FormatString.h" 16656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#include "FormatStringParsing.h" 17656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 18656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectusing clang::analyze_format_string::ArgTypeResult; 19656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectusing clang::analyze_format_string::FormatStringHandler; 20656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectusing clang::analyze_format_string::LengthModifier; 21656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectusing clang::analyze_format_string::OptionalAmount; 22656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectusing clang::analyze_format_string::ConversionSpecifier; 23656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectusing clang::analyze_printf::PrintfSpecifier; 24656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 25656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectusing namespace clang; 26656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 27656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projecttypedef clang::analyze_format_string::SpecifierResult<PrintfSpecifier> 28656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project PrintfSpecifierResult; 29656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 30656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project//===----------------------------------------------------------------------===// 31656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project// Methods for parsing format strings. 32656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project//===----------------------------------------------------------------------===// 33656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 34656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectusing analyze_format_string::ParseNonPositionAmount; 35656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 36656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic bool ParsePrecision(FormatStringHandler &H, PrintfSpecifier &FS, 37656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project const char *Start, const char *&Beg, const char *E, 38656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project unsigned *argIndex) { 39656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (argIndex) { 40656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project FS.setPrecision(ParseNonPositionAmount(Beg, E, *argIndex)); 41656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } else { 42656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project const OptionalAmount Amt = ParsePositionAmount(H, Start, Beg, E, 43656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project analyze_format_string::PrecisionPos); 44656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (Amt.isInvalid()) 45656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return true; 46656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project FS.setPrecision(Amt); 47656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 48656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return false; 49656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project} 50656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 51656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic PrintfSpecifierResult ParsePrintfSpecifier(FormatStringHandler &H, 52656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project const char *&Beg, 53656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project const char *E, 54656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project unsigned &argIndex, 55656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project const LangOptions &LO) { 56656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 57656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project using namespace clang::analyze_format_string; 58656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project using namespace clang::analyze_printf; 59221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom 60656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project const char *I = Beg; 61656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project const char *Start = 0; 62656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project UpdateOnReturn <const char*> UpdateBeg(Beg, I); 63656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 64656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project // Look for a '%' character that indicates the start of a format specifier. 65656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project for ( ; I != E ; ++I) { 66656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project char c = *I; 67656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (c == '\0') { 68656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project // Detect spurious null characters, which are likely errors. 69656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project H.HandleNullChar(I); 70656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return true; 71656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 72656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (c == '%') { 73656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project Start = I++; // Record the start of the format specifier. 74656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project break; 75656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 76656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 77656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 78656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project // No format specifier found? 79656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (!Start) 80656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return false; 81656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 82656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (I == E) { 83656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project // No more characters left? 84656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project H.HandleIncompleteSpecifier(Start, E - Start); 85656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return true; 86656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 87656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 88656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project PrintfSpecifier FS; 89656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (ParseArgPosition(H, FS, Start, I, E)) 90656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return true; 91656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 92656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (I == E) { 93656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project // No more characters left? 94656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project H.HandleIncompleteSpecifier(Start, E - Start); 95656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return true; 96656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 97656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 98656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project // Look for flags (if any). 99656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project bool hasMore = true; 100656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project for ( ; I != E; ++I) { 101656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project switch (*I) { 102656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project default: hasMore = false; break; 103656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project case '\'': 104656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project // FIXME: POSIX specific. Always accept? 105656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project FS.setHasThousandsGrouping(I); 106656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project break; 107656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project case '-': FS.setIsLeftJustified(I); break; 108656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project case '+': FS.setHasPlusPrefix(I); break; 109656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project case ' ': FS.setHasSpacePrefix(I); break; 110656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project case '#': FS.setHasAlternativeForm(I); break; 111656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project case '0': FS.setHasLeadingZeros(I); break; 112656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 113656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (!hasMore) 114656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project break; 115656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 116656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 117656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (I == E) { 118656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project // No more characters left? 119656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project H.HandleIncompleteSpecifier(Start, E - Start); 120656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return true; 121656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project } 122221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom 123221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom // Look for the field width (if any). 124221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom if (ParseFieldWidth(H, FS, Start, I, E, 125221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom FS.usesPositionalArg() ? 0 : &argIndex)) 126221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom return true; 127221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom 128221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom if (I == E) { 129221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom // No more characters left? 130221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom H.HandleIncompleteSpecifier(Start, E - Start); 131221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom return true; 132221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom } 133221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom 134221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom // Look for the precision (if any). 135221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom if (*I == '.') { 136221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom ++I; 137221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom if (I == E) { 138221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom H.HandleIncompleteSpecifier(Start, E - Start); 139221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom return true; 140221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom } 141221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom 142221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom if (ParsePrecision(H, FS, Start, I, E, 143221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom FS.usesPositionalArg() ? 0 : &argIndex)) 144221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom return true; 145221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom 146221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom if (I == E) { 147221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom // No more characters left? 148221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom H.HandleIncompleteSpecifier(Start, E - Start); 149221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom return true; 150221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom } 151221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom } 152221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom 153221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom // Look for the length modifier. 154221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom if (ParseLengthModifier(FS, I, E, LO) && I == E) { 155221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom // No more characters left? 156221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom H.HandleIncompleteSpecifier(Start, E - Start); 157221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom return true; 158221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom } 159221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom 160221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom if (*I == '\0') { 161221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom // Detect spurious null characters, which are likely errors. 162221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom H.HandleNullChar(I); 163221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom return true; 164221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom } 165221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom 166221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom // Finally, look for the conversion specifier. 167221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom const char *conversionPosition = I++; 168221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom ConversionSpecifier::Kind k = ConversionSpecifier::InvalidSpecifier; 169221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom switch (*conversionPosition) { 170221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom default: 171221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom break; 172221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom // C99: 7.19.6.1 (section 8). 173221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom case '%': k = ConversionSpecifier::PercentArg; break; 174221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom case 'A': k = ConversionSpecifier::AArg; break; 175221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom case 'E': k = ConversionSpecifier::EArg; break; 176221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom case 'F': k = ConversionSpecifier::FArg; break; 177221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom case 'G': k = ConversionSpecifier::GArg; break; 178221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom case 'X': k = ConversionSpecifier::XArg; break; 179221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom case 'a': k = ConversionSpecifier::aArg; break; 180221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom case 'c': k = ConversionSpecifier::cArg; break; 181221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom case 'd': k = ConversionSpecifier::dArg; break; 182221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom case 'e': k = ConversionSpecifier::eArg; break; 183221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom case 'f': k = ConversionSpecifier::fArg; break; 184221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom case 'g': k = ConversionSpecifier::gArg; break; 185221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom case 'i': k = ConversionSpecifier::iArg; break; 186221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom case 'n': k = ConversionSpecifier::nArg; break; 187221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom case 'o': k = ConversionSpecifier::oArg; break; 188221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom case 'p': k = ConversionSpecifier::pArg; break; 189221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom case 's': k = ConversionSpecifier::sArg; break; 190221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom case 'u': k = ConversionSpecifier::uArg; break; 191221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom case 'x': k = ConversionSpecifier::xArg; break; 192221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom // POSIX specific. 193221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom case 'C': k = ConversionSpecifier::CArg; break; 194221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom case 'S': k = ConversionSpecifier::SArg; break; 195221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom // Objective-C. 196221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom case '@': k = ConversionSpecifier::ObjCObjArg; break; 197221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom // Glibc specific. 198221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom case 'm': k = ConversionSpecifier::PrintErrno; break; 199221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom } 200221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom PrintfConversionSpecifier CS(conversionPosition, k); 201221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom FS.setConversionSpecifier(CS); 202221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom if (CS.consumesDataArgument() && !FS.usesPositionalArg()) 203221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom FS.setArgIndex(argIndex++); 204221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom 205221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom if (k == ConversionSpecifier::InvalidSpecifier) { 206221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom // Assume the conversion takes one argument. 207221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom return !H.HandleInvalidPrintfConversionSpecifier(FS, Start, I - Start); 208221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom } 209221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom return PrintfSpecifierResult(Start, FS); 210221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom} 211221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom 212221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrombool clang::analyze_format_string::ParsePrintfString(FormatStringHandler &H, 213221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom const char *I, 214221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom const char *E, 215221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom const LangOptions &LO) { 216221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom 217221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom unsigned argIndex = 0; 218221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom 219221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom // Keep looking for a format specifier until we have exhausted the string. 220221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom while (I != E) { 221221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom const PrintfSpecifierResult &FSR = ParsePrintfSpecifier(H, I, E, argIndex, 222221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom LO); 223221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom // Did a fail-stop error of any kind occur when parsing the specifier? 224221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom // If so, don't do any more processing. 225221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom if (FSR.shouldStop()) 226221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom return true;; 227221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom // Did we exhaust the string or encounter an error that 228221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom // we can recover from? 229221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom if (!FSR.hasValue()) 230221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom continue; 231221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom // We have a format specifier. Pass it to the callback. 232221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom if (!H.HandlePrintfSpecifier(FSR.getValue(), FSR.getStart(), 233221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom I - FSR.getStart())) 234221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom return true; 235221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom } 236221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom assert(I == E && "Format string not exhausted"); 237221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom return false; 238221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom} 239221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom 240221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom//===----------------------------------------------------------------------===// 241221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom// Methods on PrintfSpecifier. 242221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom//===----------------------------------------------------------------------===// 243221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom 244221304ee937bc0910948a8be1320cb8cc4eb6d36Brian CarlstromArgTypeResult PrintfSpecifier::getArgType(ASTContext &Ctx, 245221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom bool IsObjCLiteral) const { 246221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom const PrintfConversionSpecifier &CS = getConversionSpecifier(); 247221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom 248221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom if (!CS.consumesDataArgument()) 249221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom return ArgTypeResult::Invalid(); 250221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom 251221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom if (CS.getKind() == ConversionSpecifier::cArg) 252221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom switch (LM.getKind()) { 253221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom case LengthModifier::None: return Ctx.IntTy; 254221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom case LengthModifier::AsLong: 255221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom return ArgTypeResult(ArgTypeResult::WIntTy, "wint_t"); 256221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom default: 257221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom return ArgTypeResult::Invalid(); 258221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom } 259221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom 260221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom if (CS.isIntArg()) 261221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom switch (LM.getKind()) { 262221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom case LengthModifier::AsLongDouble: 263221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom // GNU extension. 264221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom return Ctx.LongLongTy; 265221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom case LengthModifier::None: return Ctx.IntTy; 266221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom case LengthModifier::AsChar: return ArgTypeResult::AnyCharTy; 267221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom case LengthModifier::AsShort: return Ctx.ShortTy; 268221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom case LengthModifier::AsLong: return Ctx.LongTy; 269221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom case LengthModifier::AsLongLong: return Ctx.LongLongTy; 270221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom case LengthModifier::AsIntMax: 271221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom return ArgTypeResult(Ctx.getIntMaxType(), "intmax_t"); 272221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom case LengthModifier::AsSizeT: 273221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom // FIXME: How to get the corresponding signed version of size_t? 274221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom return ArgTypeResult(); 275221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom case LengthModifier::AsPtrDiff: 276221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom return ArgTypeResult(Ctx.getPointerDiffType(), "ptrdiff_t"); 277221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom case LengthModifier::AsAllocate: 278221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom case LengthModifier::AsMAllocate: 279221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom return ArgTypeResult::Invalid(); 280221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom } 281221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom 282221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom if (CS.isUIntArg()) 283221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom switch (LM.getKind()) { 284221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom case LengthModifier::AsLongDouble: 285221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom // GNU extension. 286221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom return Ctx.UnsignedLongLongTy; 287221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom case LengthModifier::None: return Ctx.UnsignedIntTy; 288221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom case LengthModifier::AsChar: return Ctx.UnsignedCharTy; 289221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom case LengthModifier::AsShort: return Ctx.UnsignedShortTy; 290221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom case LengthModifier::AsLong: return Ctx.UnsignedLongTy; 291221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom case LengthModifier::AsLongLong: return Ctx.UnsignedLongLongTy; 292221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom case LengthModifier::AsIntMax: 293221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom return ArgTypeResult(Ctx.getUIntMaxType(), "uintmax_t"); 294221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom case LengthModifier::AsSizeT: 295221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom return ArgTypeResult(Ctx.getSizeType(), "size_t"); 296221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom case LengthModifier::AsPtrDiff: 297221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom // FIXME: How to get the corresponding unsigned 298221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom // version of ptrdiff_t? 299221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom return ArgTypeResult(); 300221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom case LengthModifier::AsAllocate: 301221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom case LengthModifier::AsMAllocate: 302221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom return ArgTypeResult::Invalid(); 303221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom } 304221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom 305221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom if (CS.isDoubleArg()) { 306221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom if (LM.getKind() == LengthModifier::AsLongDouble) 307221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom return Ctx.LongDoubleTy; 308221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom return Ctx.DoubleTy; 309221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom } 310221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom 311221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom switch (CS.getKind()) { 312221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom case ConversionSpecifier::sArg: 313221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom if (LM.getKind() == LengthModifier::AsWideChar) { 314221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom if (IsObjCLiteral) 315221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom return Ctx.getPointerType(Ctx.UnsignedShortTy.withConst()); 316221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom return ArgTypeResult(ArgTypeResult::WCStrTy, "wchar_t *"); 317221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom } 318221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom return ArgTypeResult::CStrTy; 319221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom case ConversionSpecifier::SArg: 320221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom if (IsObjCLiteral) 321221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom return Ctx.getPointerType(Ctx.UnsignedShortTy.withConst()); 322221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom return ArgTypeResult(ArgTypeResult::WCStrTy, "wchar_t *"); 323221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom case ConversionSpecifier::CArg: 324221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom if (IsObjCLiteral) 325221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom return Ctx.UnsignedShortTy; 326221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom return ArgTypeResult(Ctx.WCharTy, "wchar_t"); 327221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom case ConversionSpecifier::pArg: 328221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom return ArgTypeResult::CPointerTy; 329221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom case ConversionSpecifier::ObjCObjArg: 330221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom return ArgTypeResult::ObjCPointerTy; 331221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom default: 332221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom break; 333221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom } 334221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom 335221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom // FIXME: Handle other cases. 336221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom return ArgTypeResult(); 337221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom} 338221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom 339221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrombool PrintfSpecifier::fixType(QualType QT, const LangOptions &LangOpt) { 340221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom // Handle strings first (char *, wchar_t *) 341221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom if (QT->isPointerType() && (QT->getPointeeType()->isAnyCharacterType())) { 342221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom CS.setKind(ConversionSpecifier::sArg); 343221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom 344221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom // Disable irrelevant flags 345221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom HasAlternativeForm = 0; 346221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom HasLeadingZeroes = 0; 347221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom 348221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom // Set the long length modifier for wide characters 349221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom if (QT->getPointeeType()->isWideCharType()) 350221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom LM.setKind(LengthModifier::AsWideChar); 351221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom else 352221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom LM.setKind(LengthModifier::None); 353221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom 354221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom return true; 355221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom } 356221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom 357221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom // We can only work with builtin types. 358221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom const BuiltinType *BT = QT->getAs<BuiltinType>(); 359221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom if (!BT) 360221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom return false; 361221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom 362221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom // Set length modifier 363221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom switch (BT->getKind()) { 364221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom case BuiltinType::Bool: 365221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom case BuiltinType::WChar_U: 366221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom case BuiltinType::WChar_S: 367221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom case BuiltinType::Char16: 368221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom case BuiltinType::Char32: 369221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom case BuiltinType::UInt128: 370221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom case BuiltinType::Int128: 371221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom case BuiltinType::Half: 372221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom // Various types which are non-trivial to correct. 373221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom return false; 374221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom 375221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom#define SIGNED_TYPE(Id, SingletonId) 376221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom#define UNSIGNED_TYPE(Id, SingletonId) 377221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom#define FLOATING_TYPE(Id, SingletonId) 378221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom#define BUILTIN_TYPE(Id, SingletonId) \ 379221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom case BuiltinType::Id: 380221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom#include "clang/AST/BuiltinTypes.def" 381221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom // Misc other stuff which doesn't make sense here. 382221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom return false; 383221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom 384221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom case BuiltinType::UInt: 385221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom case BuiltinType::Int: 386221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom case BuiltinType::Float: 387221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom case BuiltinType::Double: 388221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom LM.setKind(LengthModifier::None); 389221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom break; 390221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom 391221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom case BuiltinType::Char_U: 392221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom case BuiltinType::UChar: 393221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom case BuiltinType::Char_S: 394221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom case BuiltinType::SChar: 395221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom LM.setKind(LengthModifier::AsChar); 396221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom break; 397221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom 398221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom case BuiltinType::Short: 399221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom case BuiltinType::UShort: 400221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom LM.setKind(LengthModifier::AsShort); 401221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom break; 402221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom 403221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom case BuiltinType::Long: 404221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom case BuiltinType::ULong: 405221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom LM.setKind(LengthModifier::AsLong); 406221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom break; 407221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom 408221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom case BuiltinType::LongLong: 409221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom case BuiltinType::ULongLong: 410221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom LM.setKind(LengthModifier::AsLongLong); 411221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom break; 412221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom 413221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom case BuiltinType::LongDouble: 414221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom LM.setKind(LengthModifier::AsLongDouble); 415221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom break; 416221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom } 417221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom 418221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom // Handle size_t, ptrdiff_t, etc. that have dedicated length modifiers in C99. 419221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom if (isa<TypedefType>(QT) && (LangOpt.C99 || LangOpt.CPlusPlus0x)) { 420221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom const IdentifierInfo *Identifier = QT.getBaseTypeIdentifier(); 421221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom if (Identifier->getName() == "size_t") { 422221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom LM.setKind(LengthModifier::AsSizeT); 423221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom } else if (Identifier->getName() == "ssize_t") { 424221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom // Not C99, but common in Unix. 425221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom LM.setKind(LengthModifier::AsSizeT); 426221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom } else if (Identifier->getName() == "intmax_t") { 427221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom LM.setKind(LengthModifier::AsIntMax); 428221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom } else if (Identifier->getName() == "uintmax_t") { 429221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom LM.setKind(LengthModifier::AsIntMax); 430221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom } else if (Identifier->getName() == "ptrdiff_t") { 431221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom LM.setKind(LengthModifier::AsPtrDiff); 432221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom } 433221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom } 434221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom 435221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom // Set conversion specifier and disable any flags which do not apply to it. 436221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom // Let typedefs to char fall through to int, as %c is silly for uint8_t. 437221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom if (isa<TypedefType>(QT) && QT->isAnyCharacterType()) { 438221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom CS.setKind(ConversionSpecifier::cArg); 439221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom LM.setKind(LengthModifier::None); 440221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom Precision.setHowSpecified(OptionalAmount::NotSpecified); 441221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom HasAlternativeForm = 0; 442221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom HasLeadingZeroes = 0; 443221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom HasPlusPrefix = 0; 444221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom } 445221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom // Test for Floating type first as LongDouble can pass isUnsignedIntegerType 446221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom else if (QT->isRealFloatingType()) { 447221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom CS.setKind(ConversionSpecifier::fArg); 448221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom } 449221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom else if (QT->isSignedIntegerType()) { 450221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom CS.setKind(ConversionSpecifier::dArg); 451221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom HasAlternativeForm = 0; 452221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom } 453221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom else if (QT->isUnsignedIntegerType()) { 454221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom // Preserve the original formatting, e.g. 'X', 'o'. 455221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom if (!cast<PrintfConversionSpecifier>(CS).isUIntArg()) 456221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom CS.setKind(ConversionSpecifier::uArg); 457221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom HasAlternativeForm = 0; 458221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom HasPlusPrefix = 0; 459221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom } else { 460221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom llvm_unreachable("Unexpected type"); 461221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom } 462221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom 463221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom return true; 464221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom} 465221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom 466221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstromvoid PrintfSpecifier::toString(raw_ostream &os) const { 467221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom // Whilst some features have no defined order, we are using the order 468221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom // appearing in the C99 standard (ISO/IEC 9899:1999 (E) 7.19.6.1) 469221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom os << "%"; 470221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom 471221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom // Positional args 472221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom if (usesPositionalArg()) { 473221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom os << getPositionalArgIndex() << "$"; 474221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom } 475221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom 476221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom // Conversion flags 477221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom if (IsLeftJustified) os << "-"; 478221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom if (HasPlusPrefix) os << "+"; 479221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom if (HasSpacePrefix) os << " "; 480221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom if (HasAlternativeForm) os << "#"; 481221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom if (HasLeadingZeroes) os << "0"; 482221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom 483221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom // Minimum field width 484221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom FieldWidth.toString(os); 485221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom // Precision 486221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom Precision.toString(os); 487221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom // Length modifier 488221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom os << LM.toString(); 489221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom // Conversion specifier 490221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom os << CS.toString(); 491221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom} 492221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom 493221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrombool PrintfSpecifier::hasValidPlusPrefix() const { 494221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom if (!HasPlusPrefix) 495221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom return true; 496221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom 497221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom // The plus prefix only makes sense for signed conversions 498221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom switch (CS.getKind()) { 499221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom case ConversionSpecifier::dArg: 500221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom case ConversionSpecifier::iArg: 501221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom case ConversionSpecifier::fArg: 502221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom case ConversionSpecifier::FArg: 503221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom case ConversionSpecifier::eArg: 504221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom case ConversionSpecifier::EArg: 505221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom case ConversionSpecifier::gArg: 506221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom case ConversionSpecifier::GArg: 507221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom case ConversionSpecifier::aArg: 508221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom case ConversionSpecifier::AArg: 509221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom return true; 510221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom 511221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom default: 512221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom return false; 513221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom } 514221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom} 515221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom 516221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrombool PrintfSpecifier::hasValidAlternativeForm() const { 517221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom if (!HasAlternativeForm) 518221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom return true; 519221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom 520221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom // Alternate form flag only valid with the oxXaAeEfFgG conversions 521221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom switch (CS.getKind()) { 522221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom case ConversionSpecifier::oArg: 523221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom case ConversionSpecifier::xArg: 524221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom case ConversionSpecifier::XArg: 525221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom case ConversionSpecifier::aArg: 526221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom case ConversionSpecifier::AArg: 527221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom case ConversionSpecifier::eArg: 528221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom case ConversionSpecifier::EArg: 529221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom case ConversionSpecifier::fArg: 530221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom case ConversionSpecifier::FArg: 531221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom case ConversionSpecifier::gArg: 532221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom case ConversionSpecifier::GArg: 533221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom return true; 534221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom 535221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom default: 536221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom return false; 537221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom } 538221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom} 539221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom 540221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrombool PrintfSpecifier::hasValidLeadingZeros() const { 541221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom if (!HasLeadingZeroes) 542221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom return true; 543221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom 544221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom // Leading zeroes flag only valid with the diouxXaAeEfFgG conversions 545221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom switch (CS.getKind()) { 546221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom case ConversionSpecifier::dArg: 547221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom case ConversionSpecifier::iArg: 548221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom case ConversionSpecifier::oArg: 549221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom case ConversionSpecifier::uArg: 550221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom case ConversionSpecifier::xArg: 551221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom case ConversionSpecifier::XArg: 552221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom case ConversionSpecifier::aArg: 553221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom case ConversionSpecifier::AArg: 554221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom case ConversionSpecifier::eArg: 555221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom case ConversionSpecifier::EArg: 556221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom case ConversionSpecifier::fArg: 557221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom case ConversionSpecifier::FArg: 558221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom case ConversionSpecifier::gArg: 559221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom case ConversionSpecifier::GArg: 560221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom return true; 561221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom 562221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom default: 563221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom return false; 564221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom } 565221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom} 566221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom 567221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrombool PrintfSpecifier::hasValidSpacePrefix() const { 568221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom if (!HasSpacePrefix) 569221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom return true; 570221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom 571221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom // The space prefix only makes sense for signed conversions 572221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom switch (CS.getKind()) { 573221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom case ConversionSpecifier::dArg: 574221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom case ConversionSpecifier::iArg: 575221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom case ConversionSpecifier::fArg: 576221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom case ConversionSpecifier::FArg: 577221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom case ConversionSpecifier::eArg: 578221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom case ConversionSpecifier::EArg: 579221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom case ConversionSpecifier::gArg: 580221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom case ConversionSpecifier::GArg: 581221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom case ConversionSpecifier::aArg: 582221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom case ConversionSpecifier::AArg: 583221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom return true; 584221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom 585221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom default: 586221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom return false; 587221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom } 588221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom} 589221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom 590221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrombool PrintfSpecifier::hasValidLeftJustified() const { 591221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom if (!IsLeftJustified) 592221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom return true; 593221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom 594221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom // The left justified flag is valid for all conversions except n 595221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom switch (CS.getKind()) { 596221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom case ConversionSpecifier::nArg: 597221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom return false; 598221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom 599221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom default: 600221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom return true; 601221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom } 602221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom} 603221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom 604221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrombool PrintfSpecifier::hasValidThousandsGroupingPrefix() const { 605221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom if (!HasThousandsGrouping) 606221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom return true; 607221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom 608221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom switch (CS.getKind()) { 609221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom case ConversionSpecifier::dArg: 610221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom case ConversionSpecifier::iArg: 611221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom case ConversionSpecifier::uArg: 612221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom case ConversionSpecifier::fArg: 613221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom case ConversionSpecifier::FArg: 614221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom case ConversionSpecifier::gArg: 615221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom case ConversionSpecifier::GArg: 616221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom return true; 617221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom default: 618221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom return false; 619221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom } 620221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom} 621221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom 622221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrombool PrintfSpecifier::hasValidPrecision() const { 623656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project if (Precision.getHowSpecified() == OptionalAmount::NotSpecified) 624656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return true; 625656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project 626656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project // Precision is only valid with the diouxXaAeEfFgGs conversions 627656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project switch (CS.getKind()) { 628656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project case ConversionSpecifier::dArg: 629656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project case ConversionSpecifier::iArg: 630656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project case ConversionSpecifier::oArg: 631656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project case ConversionSpecifier::uArg: 632656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project case ConversionSpecifier::xArg: 633656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project case ConversionSpecifier::XArg: 634656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project case ConversionSpecifier::aArg: 635656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project case ConversionSpecifier::AArg: 636656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project case ConversionSpecifier::eArg: 637656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project case ConversionSpecifier::EArg: 638656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project case ConversionSpecifier::fArg: 639656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project case ConversionSpecifier::FArg: 640656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project case ConversionSpecifier::gArg: 641656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project case ConversionSpecifier::GArg: 642656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project case ConversionSpecifier::sArg: 643656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project return true; 644221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom 645221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom default: 646221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom return false; 647221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom } 648221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom} 649221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrombool PrintfSpecifier::hasValidFieldWidth() const { 650221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom if (FieldWidth.getHowSpecified() == OptionalAmount::NotSpecified) 651221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom return true; 652221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom 653221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom // The field width is valid for all conversions except n 654221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom switch (CS.getKind()) { 655221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom case ConversionSpecifier::nArg: 656221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom return false; 657221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom 658221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom default: 659221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom return true; 660221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom } 661221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom} 662221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom