1826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek// FormatString.cpp - Common stuff for handling printf/scanf formats -*- C++ -*- 2826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek// 3826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek// The LLVM Compiler Infrastructure 4826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek// 5826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek// This file is distributed under the University of Illinois Open Source 6826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek// License. See LICENSE.TXT for details. 7826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek// 8826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek//===----------------------------------------------------------------------===// 9826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek// 10826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek// Shared details for processing format strings of printf and scanf 11826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek// (and friends). 12826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek// 13826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek//===----------------------------------------------------------------------===// 14826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek 15826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek#include "FormatStringParsing.h" 16d02deebce5f1b283101e035a7f5d5bab0d2068ecHans Wennborg#include "clang/Basic/LangOptions.h" 17bbb6bb4952b77e57b842b4d3096848123ae690e7Jordan Rose#include "clang/Basic/TargetInfo.h" 18826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek 19f3749f4168c5cee59627a681ca4ca6e4116d0761Hans Wennborgusing clang::analyze_format_string::ArgType; 20826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenekusing clang::analyze_format_string::FormatStringHandler; 21826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenekusing clang::analyze_format_string::FormatSpecifier; 22826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenekusing clang::analyze_format_string::LengthModifier; 23826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenekusing clang::analyze_format_string::OptionalAmount; 24826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenekusing clang::analyze_format_string::PositionContext; 25a412a499162c46211c10ad92045b9b5fd2298edeTed Kremenekusing clang::analyze_format_string::ConversionSpecifier; 26826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenekusing namespace clang; 27826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek 28826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek// Key function to FormatStringHandler. 29826a3457f737f1fc45a22954fd1bfde38160c165Ted KremenekFormatStringHandler::~FormatStringHandler() {} 30826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek 31826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek//===----------------------------------------------------------------------===// 32826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek// Functions for parsing format strings components in both printf and 33826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek// scanf format strings. 34826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek//===----------------------------------------------------------------------===// 35826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek 36826a3457f737f1fc45a22954fd1bfde38160c165Ted KremenekOptionalAmount 37826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenekclang::analyze_format_string::ParseAmount(const char *&Beg, const char *E) { 38826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek const char *I = Beg; 39826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek UpdateOnReturn <const char*> UpdateBeg(Beg, I); 40826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek 41826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek unsigned accumulator = 0; 42826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek bool hasDigits = false; 43826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek 44826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek for ( ; I != E; ++I) { 45826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek char c = *I; 46826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek if (c >= '0' && c <= '9') { 47826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek hasDigits = true; 48826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek accumulator = (accumulator * 10) + (c - '0'); 49826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek continue; 50826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek } 51826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek 52826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek if (hasDigits) 53826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek return OptionalAmount(OptionalAmount::Constant, accumulator, Beg, I - Beg, 54826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek false); 55826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek 56826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek break; 57826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek } 58826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek 59826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek return OptionalAmount(); 60826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek} 61826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek 62826a3457f737f1fc45a22954fd1bfde38160c165Ted KremenekOptionalAmount 63826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenekclang::analyze_format_string::ParseNonPositionAmount(const char *&Beg, 64826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek const char *E, 65826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek unsigned &argIndex) { 66826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek if (*Beg == '*') { 67826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek ++Beg; 68826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek return OptionalAmount(OptionalAmount::Arg, argIndex++, Beg, 0, false); 69826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek } 70826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek 71826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek return ParseAmount(Beg, E); 72826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek} 73826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek 74826a3457f737f1fc45a22954fd1bfde38160c165Ted KremenekOptionalAmount 75826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenekclang::analyze_format_string::ParsePositionAmount(FormatStringHandler &H, 76826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek const char *Start, 77826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek const char *&Beg, 78826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek const char *E, 79826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek PositionContext p) { 80826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek if (*Beg == '*') { 81826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek const char *I = Beg + 1; 82826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek const OptionalAmount &Amt = ParseAmount(I, E); 83826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek 84826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek if (Amt.getHowSpecified() == OptionalAmount::NotSpecified) { 85826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek H.HandleInvalidPosition(Beg, I - Beg, p); 86826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek return OptionalAmount(false); 87826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek } 88826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek 89826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek if (I == E) { 90826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek // No more characters left? 91826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek H.HandleIncompleteSpecifier(Start, E - Start); 92826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek return OptionalAmount(false); 93826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek } 94826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek 95826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek assert(Amt.getHowSpecified() == OptionalAmount::Constant); 96826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek 97826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek if (*I == '$') { 98826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek // Handle positional arguments 99826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek 100826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek // Special case: '*0$', since this is an easy mistake. 101826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek if (Amt.getConstantAmount() == 0) { 102826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek H.HandleZeroPosition(Beg, I - Beg + 1); 103826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek return OptionalAmount(false); 104826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek } 105826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek 106826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek const char *Tmp = Beg; 107826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek Beg = ++I; 108826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek 109826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek return OptionalAmount(OptionalAmount::Arg, Amt.getConstantAmount() - 1, 110826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek Tmp, 0, true); 111826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek } 112826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek 113826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek H.HandleInvalidPosition(Beg, I - Beg, p); 114826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek return OptionalAmount(false); 115826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek } 116826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek 117826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek return ParseAmount(Beg, E); 118826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek} 119826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek 120826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek 121826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenekbool 122826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenekclang::analyze_format_string::ParseFieldWidth(FormatStringHandler &H, 123826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek FormatSpecifier &CS, 124826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek const char *Start, 125826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek const char *&Beg, const char *E, 126826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek unsigned *argIndex) { 127826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek // FIXME: Support negative field widths. 128826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek if (argIndex) { 129826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek CS.setFieldWidth(ParseNonPositionAmount(Beg, E, *argIndex)); 130826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek } 131826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek else { 132826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek const OptionalAmount Amt = 133826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek ParsePositionAmount(H, Start, Beg, E, 134826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek analyze_format_string::FieldWidthPos); 135826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek 136826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek if (Amt.isInvalid()) 137826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek return true; 138826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek CS.setFieldWidth(Amt); 139826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek } 140826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek return false; 141826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek} 142826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek 143826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenekbool 144826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenekclang::analyze_format_string::ParseArgPosition(FormatStringHandler &H, 145826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek FormatSpecifier &FS, 146826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek const char *Start, 147826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek const char *&Beg, 148826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek const char *E) { 149826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek const char *I = Beg; 150826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek 151826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek const OptionalAmount &Amt = ParseAmount(I, E); 152826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek 153826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek if (I == E) { 154826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek // No more characters left? 155826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek H.HandleIncompleteSpecifier(Start, E - Start); 156826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek return true; 157826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek } 158826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek 159826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek if (Amt.getHowSpecified() == OptionalAmount::Constant && *(I++) == '$') { 160f85626453123f9691bcef13cff963f556e209c27Hans Wennborg // Warn that positional arguments are non-standard. 161f85626453123f9691bcef13cff963f556e209c27Hans Wennborg H.HandlePosition(Start, I - Start); 162f85626453123f9691bcef13cff963f556e209c27Hans Wennborg 163826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek // Special case: '%0$', since this is an easy mistake. 164826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek if (Amt.getConstantAmount() == 0) { 165826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek H.HandleZeroPosition(Start, I - Start); 166826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek return true; 167826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek } 168826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek 169826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek FS.setArgIndex(Amt.getConstantAmount() - 1); 170826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek FS.setUsesPositionalArg(); 171826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek // Update the caller's pointer if we decided to consume 172826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek // these characters. 173826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek Beg = I; 174826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek return false; 175826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek } 176826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek 177826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek return false; 178826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek} 179826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek 180826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenekbool 181826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenekclang::analyze_format_string::ParseLengthModifier(FormatSpecifier &FS, 182826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek const char *&I, 183d02deebce5f1b283101e035a7f5d5bab0d2068ecHans Wennborg const char *E, 184d02deebce5f1b283101e035a7f5d5bab0d2068ecHans Wennborg const LangOptions &LO, 185d02deebce5f1b283101e035a7f5d5bab0d2068ecHans Wennborg bool IsScanf) { 186826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek LengthModifier::Kind lmKind = LengthModifier::None; 187826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek const char *lmPosition = I; 188826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek switch (*I) { 189826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek default: 190826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek return false; 191826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek case 'h': 192826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek ++I; 1936ca4a9ae99d65948e578d3e7d1f58ab6a947d2d7Ted Kremenek lmKind = (I != E && *I == 'h') ? (++I, LengthModifier::AsChar) 1946ca4a9ae99d65948e578d3e7d1f58ab6a947d2d7Ted Kremenek : LengthModifier::AsShort; 195826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek break; 196826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek case 'l': 197826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek ++I; 1986ca4a9ae99d65948e578d3e7d1f58ab6a947d2d7Ted Kremenek lmKind = (I != E && *I == 'l') ? (++I, LengthModifier::AsLongLong) 1996ca4a9ae99d65948e578d3e7d1f58ab6a947d2d7Ted Kremenek : LengthModifier::AsLong; 200826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek break; 201826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek case 'j': lmKind = LengthModifier::AsIntMax; ++I; break; 202826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek case 'z': lmKind = LengthModifier::AsSizeT; ++I; break; 203826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek case 't': lmKind = LengthModifier::AsPtrDiff; ++I; break; 204826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek case 'L': lmKind = LengthModifier::AsLongDouble; ++I; break; 20532addd519c6699000ff79c387a1c87f0ab7c3698Hans Wennborg case 'q': lmKind = LengthModifier::AsQuad; ++I; break; 206d02deebce5f1b283101e035a7f5d5bab0d2068ecHans Wennborg case 'a': 20780ad52f327b532bded5c5b0ee38779d841c6cd35Richard Smith if (IsScanf && !LO.C99 && !LO.CPlusPlus11) { 208d02deebce5f1b283101e035a7f5d5bab0d2068ecHans Wennborg // For scanf in C90, look at the next character to see if this should 209d02deebce5f1b283101e035a7f5d5bab0d2068ecHans Wennborg // be parsed as the GNU extension 'a' length modifier. If not, this 210d02deebce5f1b283101e035a7f5d5bab0d2068ecHans Wennborg // will be parsed as a conversion specifier. 211d02deebce5f1b283101e035a7f5d5bab0d2068ecHans Wennborg ++I; 212d02deebce5f1b283101e035a7f5d5bab0d2068ecHans Wennborg if (I != E && (*I == 's' || *I == 'S' || *I == '[')) { 213d02deebce5f1b283101e035a7f5d5bab0d2068ecHans Wennborg lmKind = LengthModifier::AsAllocate; 214d02deebce5f1b283101e035a7f5d5bab0d2068ecHans Wennborg break; 215d02deebce5f1b283101e035a7f5d5bab0d2068ecHans Wennborg } 216d02deebce5f1b283101e035a7f5d5bab0d2068ecHans Wennborg --I; 217d02deebce5f1b283101e035a7f5d5bab0d2068ecHans Wennborg } 218d02deebce5f1b283101e035a7f5d5bab0d2068ecHans Wennborg return false; 21937969b7e14d6a4dfd934ef6d3738cc90b832ec1dHans Wennborg case 'm': 22037969b7e14d6a4dfd934ef6d3738cc90b832ec1dHans Wennborg if (IsScanf) { 22137969b7e14d6a4dfd934ef6d3738cc90b832ec1dHans Wennborg lmKind = LengthModifier::AsMAllocate; 22237969b7e14d6a4dfd934ef6d3738cc90b832ec1dHans Wennborg ++I; 22337969b7e14d6a4dfd934ef6d3738cc90b832ec1dHans Wennborg break; 22437969b7e14d6a4dfd934ef6d3738cc90b832ec1dHans Wennborg } 22537969b7e14d6a4dfd934ef6d3738cc90b832ec1dHans Wennborg return false; 226826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek } 227826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek LengthModifier lm(lmPosition, lmKind); 228826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek FS.setLengthModifier(lm); 229826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek return true; 230826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek} 231826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek 232826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek//===----------------------------------------------------------------------===// 233f3749f4168c5cee59627a681ca4ca6e4116d0761Hans Wennborg// Methods on ArgType. 234826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek//===----------------------------------------------------------------------===// 235826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek 236f3749f4168c5cee59627a681ca4ca6e4116d0761Hans Wennborgbool ArgType::matchesType(ASTContext &C, QualType argTy) const { 23758e1e54476d610d6c33ef483f216ed8a1282d35cHans Wennborg if (Ptr) { 23858e1e54476d610d6c33ef483f216ed8a1282d35cHans Wennborg // It has to be a pointer. 23958e1e54476d610d6c33ef483f216ed8a1282d35cHans Wennborg const PointerType *PT = argTy->getAs<PointerType>(); 24058e1e54476d610d6c33ef483f216ed8a1282d35cHans Wennborg if (!PT) 24158e1e54476d610d6c33ef483f216ed8a1282d35cHans Wennborg return false; 24258e1e54476d610d6c33ef483f216ed8a1282d35cHans Wennborg 24358e1e54476d610d6c33ef483f216ed8a1282d35cHans Wennborg // We cannot write through a const qualified pointer. 24458e1e54476d610d6c33ef483f216ed8a1282d35cHans Wennborg if (PT->getPointeeType().isConstQualified()) 24558e1e54476d610d6c33ef483f216ed8a1282d35cHans Wennborg return false; 24658e1e54476d610d6c33ef483f216ed8a1282d35cHans Wennborg 24758e1e54476d610d6c33ef483f216ed8a1282d35cHans Wennborg argTy = PT->getPointeeType(); 24858e1e54476d610d6c33ef483f216ed8a1282d35cHans Wennborg } 24958e1e54476d610d6c33ef483f216ed8a1282d35cHans Wennborg 250826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek switch (K) { 251826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek case InvalidTy: 252f3749f4168c5cee59627a681ca4ca6e4116d0761Hans Wennborg llvm_unreachable("ArgType must be valid"); 253826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek 254826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek case UnknownTy: 255826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek return true; 2566ca4a9ae99d65948e578d3e7d1f58ab6a947d2d7Ted Kremenek 2576ca4a9ae99d65948e578d3e7d1f58ab6a947d2d7Ted Kremenek case AnyCharTy: { 258ee0259d308e72141982a85b40863e760a8447edfJordan Rose if (const EnumType *ETy = argTy->getAs<EnumType>()) 259ee0259d308e72141982a85b40863e760a8447edfJordan Rose argTy = ETy->getDecl()->getIntegerType(); 260ee0259d308e72141982a85b40863e760a8447edfJordan Rose 2616ca4a9ae99d65948e578d3e7d1f58ab6a947d2d7Ted Kremenek if (const BuiltinType *BT = argTy->getAs<BuiltinType>()) 2626ca4a9ae99d65948e578d3e7d1f58ab6a947d2d7Ted Kremenek switch (BT->getKind()) { 2636ca4a9ae99d65948e578d3e7d1f58ab6a947d2d7Ted Kremenek default: 2646ca4a9ae99d65948e578d3e7d1f58ab6a947d2d7Ted Kremenek break; 2656ca4a9ae99d65948e578d3e7d1f58ab6a947d2d7Ted Kremenek case BuiltinType::Char_S: 2666ca4a9ae99d65948e578d3e7d1f58ab6a947d2d7Ted Kremenek case BuiltinType::SChar: 2676ca4a9ae99d65948e578d3e7d1f58ab6a947d2d7Ted Kremenek case BuiltinType::UChar: 2686ca4a9ae99d65948e578d3e7d1f58ab6a947d2d7Ted Kremenek case BuiltinType::Char_U: 2696ca4a9ae99d65948e578d3e7d1f58ab6a947d2d7Ted Kremenek return true; 2706ca4a9ae99d65948e578d3e7d1f58ab6a947d2d7Ted Kremenek } 2716ca4a9ae99d65948e578d3e7d1f58ab6a947d2d7Ted Kremenek return false; 2726ca4a9ae99d65948e578d3e7d1f58ab6a947d2d7Ted Kremenek } 2736ca4a9ae99d65948e578d3e7d1f58ab6a947d2d7Ted Kremenek 274826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek case SpecificTy: { 275ee0259d308e72141982a85b40863e760a8447edfJordan Rose if (const EnumType *ETy = argTy->getAs<EnumType>()) 276ee0259d308e72141982a85b40863e760a8447edfJordan Rose argTy = ETy->getDecl()->getIntegerType(); 277826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek argTy = C.getCanonicalType(argTy).getUnqualifiedType(); 278ee0259d308e72141982a85b40863e760a8447edfJordan Rose 279687b5df89d4ba91219df578d02087c68c09a0332Nick Lewycky if (T == argTy) 280826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek return true; 281dc00d8158db573f4a1f91cfaa2a89171c2e5f637Ted Kremenek // Check for "compatible types". 2821ad35bebcc07d34202850f46b5b7be46fda1c5d1Ted Kremenek if (const BuiltinType *BT = argTy->getAs<BuiltinType>()) 283826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek switch (BT->getKind()) { 284826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek default: 285826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek break; 286826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek case BuiltinType::Char_S: 287826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek case BuiltinType::SChar: 288dc00d8158db573f4a1f91cfaa2a89171c2e5f637Ted Kremenek case BuiltinType::Char_U: 2891ad35bebcc07d34202850f46b5b7be46fda1c5d1Ted Kremenek case BuiltinType::UChar: 290101d4e0c8ffbcdaaa58cddf1c20f98aa1b4501c4Hans Wennborg return T == C.UnsignedCharTy || T == C.SignedCharTy; 291826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek case BuiltinType::Short: 292687b5df89d4ba91219df578d02087c68c09a0332Nick Lewycky return T == C.UnsignedShortTy; 293826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek case BuiltinType::UShort: 294687b5df89d4ba91219df578d02087c68c09a0332Nick Lewycky return T == C.ShortTy; 295826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek case BuiltinType::Int: 296687b5df89d4ba91219df578d02087c68c09a0332Nick Lewycky return T == C.UnsignedIntTy; 297826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek case BuiltinType::UInt: 298687b5df89d4ba91219df578d02087c68c09a0332Nick Lewycky return T == C.IntTy; 299826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek case BuiltinType::Long: 300687b5df89d4ba91219df578d02087c68c09a0332Nick Lewycky return T == C.UnsignedLongTy; 301826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek case BuiltinType::ULong: 302687b5df89d4ba91219df578d02087c68c09a0332Nick Lewycky return T == C.LongTy; 303826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek case BuiltinType::LongLong: 304687b5df89d4ba91219df578d02087c68c09a0332Nick Lewycky return T == C.UnsignedLongLongTy; 305826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek case BuiltinType::ULongLong: 306687b5df89d4ba91219df578d02087c68c09a0332Nick Lewycky return T == C.LongLongTy; 307826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek } 308826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek return false; 309826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek } 310826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek 311826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek case CStrTy: { 312826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek const PointerType *PT = argTy->getAs<PointerType>(); 313826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek if (!PT) 314826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek return false; 315826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek QualType pointeeTy = PT->getPointeeType(); 316826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek if (const BuiltinType *BT = pointeeTy->getAs<BuiltinType>()) 317826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek switch (BT->getKind()) { 318826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek case BuiltinType::Void: 319826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek case BuiltinType::Char_U: 320826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek case BuiltinType::UChar: 321826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek case BuiltinType::Char_S: 322826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek case BuiltinType::SChar: 323826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek return true; 324826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek default: 325826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek break; 326826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek } 327826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek 328826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek return false; 329826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek } 330826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek 331826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek case WCStrTy: { 332826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek const PointerType *PT = argTy->getAs<PointerType>(); 333826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek if (!PT) 334826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek return false; 335826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek QualType pointeeTy = 336826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek C.getCanonicalType(PT->getPointeeType()).getUnqualifiedType(); 33715f92bad58c8650b1306729744b1a1230197497aHans Wennborg return pointeeTy == C.getWideCharType(); 338826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek } 3399325eaf08fcccbc0d038e703f570c64daacdaa31Ted Kremenek 3409325eaf08fcccbc0d038e703f570c64daacdaa31Ted Kremenek case WIntTy: { 341392da48160bd92ceb486792780467cbfdb2d0e8cJames Molloy 3429325eaf08fcccbc0d038e703f570c64daacdaa31Ted Kremenek QualType PromoArg = 3439325eaf08fcccbc0d038e703f570c64daacdaa31Ted Kremenek argTy->isPromotableIntegerType() 3449325eaf08fcccbc0d038e703f570c64daacdaa31Ted Kremenek ? C.getPromotedIntegerType(argTy) : argTy; 3459325eaf08fcccbc0d038e703f570c64daacdaa31Ted Kremenek 346392da48160bd92ceb486792780467cbfdb2d0e8cJames Molloy QualType WInt = C.getCanonicalType(C.getWIntType()).getUnqualifiedType(); 3479325eaf08fcccbc0d038e703f570c64daacdaa31Ted Kremenek PromoArg = C.getCanonicalType(PromoArg).getUnqualifiedType(); 3489325eaf08fcccbc0d038e703f570c64daacdaa31Ted Kremenek 349392da48160bd92ceb486792780467cbfdb2d0e8cJames Molloy // If the promoted argument is the corresponding signed type of the 350392da48160bd92ceb486792780467cbfdb2d0e8cJames Molloy // wint_t type, then it should match. 351392da48160bd92ceb486792780467cbfdb2d0e8cJames Molloy if (PromoArg->hasSignedIntegerRepresentation() && 352392da48160bd92ceb486792780467cbfdb2d0e8cJames Molloy C.getCorrespondingUnsignedType(PromoArg) == WInt) 353392da48160bd92ceb486792780467cbfdb2d0e8cJames Molloy return true; 354392da48160bd92ceb486792780467cbfdb2d0e8cJames Molloy 355392da48160bd92ceb486792780467cbfdb2d0e8cJames Molloy return WInt == PromoArg; 3569325eaf08fcccbc0d038e703f570c64daacdaa31Ted Kremenek } 357826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek 358826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek case CPointerTy: 359624259984448cf19f4e94b7e31c7c32e99a39ea5Anders Carlsson return argTy->isPointerType() || argTy->isObjCObjectPointerType() || 360afcd1954be90965d832ae56f1413beae836c3346Ted Kremenek argTy->isBlockPointerType() || argTy->isNullPtrType(); 361826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek 362b4a3ef783cb3e9c8a927130d65385988a6aabaa3Ted Kremenek case ObjCPointerTy: { 363b4a3ef783cb3e9c8a927130d65385988a6aabaa3Ted Kremenek if (argTy->getAs<ObjCObjectPointerType>() || 364b4a3ef783cb3e9c8a927130d65385988a6aabaa3Ted Kremenek argTy->getAs<BlockPointerType>()) 365b4a3ef783cb3e9c8a927130d65385988a6aabaa3Ted Kremenek return true; 366b4a3ef783cb3e9c8a927130d65385988a6aabaa3Ted Kremenek 367b4a3ef783cb3e9c8a927130d65385988a6aabaa3Ted Kremenek // Handle implicit toll-free bridging. 368b4a3ef783cb3e9c8a927130d65385988a6aabaa3Ted Kremenek if (const PointerType *PT = argTy->getAs<PointerType>()) { 369b4a3ef783cb3e9c8a927130d65385988a6aabaa3Ted Kremenek // Things such as CFTypeRef are really just opaque pointers 370b4a3ef783cb3e9c8a927130d65385988a6aabaa3Ted Kremenek // to C structs representing CF types that can often be bridged 371b4a3ef783cb3e9c8a927130d65385988a6aabaa3Ted Kremenek // to Objective-C objects. Since the compiler doesn't know which 372b4a3ef783cb3e9c8a927130d65385988a6aabaa3Ted Kremenek // structs can be toll-free bridged, we just accept them all. 373b4a3ef783cb3e9c8a927130d65385988a6aabaa3Ted Kremenek QualType pointee = PT->getPointeeType(); 374b4a3ef783cb3e9c8a927130d65385988a6aabaa3Ted Kremenek if (pointee->getAsStructureType() || pointee->isVoidType()) 375b4a3ef783cb3e9c8a927130d65385988a6aabaa3Ted Kremenek return true; 376b4a3ef783cb3e9c8a927130d65385988a6aabaa3Ted Kremenek } 377b4a3ef783cb3e9c8a927130d65385988a6aabaa3Ted Kremenek return false; 378b4a3ef783cb3e9c8a927130d65385988a6aabaa3Ted Kremenek } 379826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek } 380826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek 381f3749f4168c5cee59627a681ca4ca6e4116d0761Hans Wennborg llvm_unreachable("Invalid ArgType Kind!"); 382826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek} 383826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek 384f3749f4168c5cee59627a681ca4ca6e4116d0761Hans WennborgQualType ArgType::getRepresentativeType(ASTContext &C) const { 38558e1e54476d610d6c33ef483f216ed8a1282d35cHans Wennborg QualType Res; 386826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek switch (K) { 387826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek case InvalidTy: 388f3749f4168c5cee59627a681ca4ca6e4116d0761Hans Wennborg llvm_unreachable("No representative type for Invalid ArgType"); 389826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek case UnknownTy: 39058e1e54476d610d6c33ef483f216ed8a1282d35cHans Wennborg llvm_unreachable("No representative type for Unknown ArgType"); 3916ca4a9ae99d65948e578d3e7d1f58ab6a947d2d7Ted Kremenek case AnyCharTy: 39258e1e54476d610d6c33ef483f216ed8a1282d35cHans Wennborg Res = C.CharTy; 39358e1e54476d610d6c33ef483f216ed8a1282d35cHans Wennborg break; 394826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek case SpecificTy: 39558e1e54476d610d6c33ef483f216ed8a1282d35cHans Wennborg Res = T; 39658e1e54476d610d6c33ef483f216ed8a1282d35cHans Wennborg break; 397826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek case CStrTy: 39858e1e54476d610d6c33ef483f216ed8a1282d35cHans Wennborg Res = C.getPointerType(C.CharTy); 39958e1e54476d610d6c33ef483f216ed8a1282d35cHans Wennborg break; 400826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek case WCStrTy: 40115f92bad58c8650b1306729744b1a1230197497aHans Wennborg Res = C.getPointerType(C.getWideCharType()); 40258e1e54476d610d6c33ef483f216ed8a1282d35cHans Wennborg break; 403826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek case ObjCPointerTy: 40458e1e54476d610d6c33ef483f216ed8a1282d35cHans Wennborg Res = C.ObjCBuiltinIdTy; 40558e1e54476d610d6c33ef483f216ed8a1282d35cHans Wennborg break; 406826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek case CPointerTy: 40758e1e54476d610d6c33ef483f216ed8a1282d35cHans Wennborg Res = C.VoidPtrTy; 40858e1e54476d610d6c33ef483f216ed8a1282d35cHans Wennborg break; 4099325eaf08fcccbc0d038e703f570c64daacdaa31Ted Kremenek case WIntTy: { 41058e1e54476d610d6c33ef483f216ed8a1282d35cHans Wennborg Res = C.getWIntType(); 41158e1e54476d610d6c33ef483f216ed8a1282d35cHans Wennborg break; 4129325eaf08fcccbc0d038e703f570c64daacdaa31Ted Kremenek } 413826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek } 414826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek 41558e1e54476d610d6c33ef483f216ed8a1282d35cHans Wennborg if (Ptr) 41658e1e54476d610d6c33ef483f216ed8a1282d35cHans Wennborg Res = C.getPointerType(Res); 41758e1e54476d610d6c33ef483f216ed8a1282d35cHans Wennborg return Res; 418826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek} 419826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek 420f3749f4168c5cee59627a681ca4ca6e4116d0761Hans Wennborgstd::string ArgType::getRepresentativeTypeName(ASTContext &C) const { 421f4f0c6095d1f481b94c6821c65e3bf1c9df42af7Hans Wennborg std::string S = getRepresentativeType(C).getAsString(); 42258e1e54476d610d6c33ef483f216ed8a1282d35cHans Wennborg 42358e1e54476d610d6c33ef483f216ed8a1282d35cHans Wennborg std::string Alias; 42458e1e54476d610d6c33ef483f216ed8a1282d35cHans Wennborg if (Name) { 42558e1e54476d610d6c33ef483f216ed8a1282d35cHans Wennborg // Use a specific name for this type, e.g. "size_t". 42658e1e54476d610d6c33ef483f216ed8a1282d35cHans Wennborg Alias = Name; 42758e1e54476d610d6c33ef483f216ed8a1282d35cHans Wennborg if (Ptr) { 42858e1e54476d610d6c33ef483f216ed8a1282d35cHans Wennborg // If ArgType is actually a pointer to T, append an asterisk. 42958e1e54476d610d6c33ef483f216ed8a1282d35cHans Wennborg Alias += (Alias[Alias.size()-1] == '*') ? "*" : " *"; 43058e1e54476d610d6c33ef483f216ed8a1282d35cHans Wennborg } 43158e1e54476d610d6c33ef483f216ed8a1282d35cHans Wennborg // If Alias is the same as the underlying type, e.g. wchar_t, then drop it. 43258e1e54476d610d6c33ef483f216ed8a1282d35cHans Wennborg if (S == Alias) 43358e1e54476d610d6c33ef483f216ed8a1282d35cHans Wennborg Alias.clear(); 43458e1e54476d610d6c33ef483f216ed8a1282d35cHans Wennborg } 43558e1e54476d610d6c33ef483f216ed8a1282d35cHans Wennborg 43658e1e54476d610d6c33ef483f216ed8a1282d35cHans Wennborg if (!Alias.empty()) 43758e1e54476d610d6c33ef483f216ed8a1282d35cHans Wennborg return std::string("'") + Alias + "' (aka '" + S + "')"; 438f4f0c6095d1f481b94c6821c65e3bf1c9df42af7Hans Wennborg return std::string("'") + S + "'"; 439a792aff1c7de253b89c473fdb7eef4a5bba83aecHans Wennborg} 440a792aff1c7de253b89c473fdb7eef4a5bba83aecHans Wennborg 441a792aff1c7de253b89c473fdb7eef4a5bba83aecHans Wennborg 442826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek//===----------------------------------------------------------------------===// 443826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek// Methods on OptionalAmount. 444826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek//===----------------------------------------------------------------------===// 445826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek 446f3749f4168c5cee59627a681ca4ca6e4116d0761Hans WennborgArgType 447826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenekanalyze_format_string::OptionalAmount::getArgType(ASTContext &Ctx) const { 448826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek return Ctx.IntTy; 449826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek} 450826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek 451826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek//===----------------------------------------------------------------------===// 452826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek// Methods on LengthModifier. 453826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek//===----------------------------------------------------------------------===// 454826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek 455826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenekconst char * 456826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenekanalyze_format_string::LengthModifier::toString() const { 457826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek switch (kind) { 458826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek case AsChar: 459826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek return "hh"; 460826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek case AsShort: 461826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek return "h"; 462826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek case AsLong: // or AsWideChar 463826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek return "l"; 464826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek case AsLongLong: 465826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek return "ll"; 46632addd519c6699000ff79c387a1c87f0ab7c3698Hans Wennborg case AsQuad: 46732addd519c6699000ff79c387a1c87f0ab7c3698Hans Wennborg return "q"; 468826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek case AsIntMax: 469826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek return "j"; 470826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek case AsSizeT: 471826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek return "z"; 472826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek case AsPtrDiff: 473826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek return "t"; 474826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek case AsLongDouble: 475826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek return "L"; 476d02deebce5f1b283101e035a7f5d5bab0d2068ecHans Wennborg case AsAllocate: 477d02deebce5f1b283101e035a7f5d5bab0d2068ecHans Wennborg return "a"; 47837969b7e14d6a4dfd934ef6d3738cc90b832ec1dHans Wennborg case AsMAllocate: 47937969b7e14d6a4dfd934ef6d3738cc90b832ec1dHans Wennborg return "m"; 480826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek case None: 481826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek return ""; 482826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek } 483826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek return NULL; 484826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek} 485826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek 486826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek//===----------------------------------------------------------------------===// 487b8ec3e35d2d7a56b21cb449d4a7bde8d9d12c2a5Hans Wennborg// Methods on ConversionSpecifier. 488b8ec3e35d2d7a56b21cb449d4a7bde8d9d12c2a5Hans Wennborg//===----------------------------------------------------------------------===// 489b8ec3e35d2d7a56b21cb449d4a7bde8d9d12c2a5Hans Wennborg 490b8ec3e35d2d7a56b21cb449d4a7bde8d9d12c2a5Hans Wennborgconst char *ConversionSpecifier::toString() const { 491b8ec3e35d2d7a56b21cb449d4a7bde8d9d12c2a5Hans Wennborg switch (kind) { 492b8ec3e35d2d7a56b21cb449d4a7bde8d9d12c2a5Hans Wennborg case dArg: return "d"; 493275b6f52c7bcafc1f3cf291813b5c60ee776965aJordan Rose case DArg: return "D"; 494b8ec3e35d2d7a56b21cb449d4a7bde8d9d12c2a5Hans Wennborg case iArg: return "i"; 495b8ec3e35d2d7a56b21cb449d4a7bde8d9d12c2a5Hans Wennborg case oArg: return "o"; 496275b6f52c7bcafc1f3cf291813b5c60ee776965aJordan Rose case OArg: return "O"; 497b8ec3e35d2d7a56b21cb449d4a7bde8d9d12c2a5Hans Wennborg case uArg: return "u"; 498275b6f52c7bcafc1f3cf291813b5c60ee776965aJordan Rose case UArg: return "U"; 499b8ec3e35d2d7a56b21cb449d4a7bde8d9d12c2a5Hans Wennborg case xArg: return "x"; 500b8ec3e35d2d7a56b21cb449d4a7bde8d9d12c2a5Hans Wennborg case XArg: return "X"; 501b8ec3e35d2d7a56b21cb449d4a7bde8d9d12c2a5Hans Wennborg case fArg: return "f"; 502b8ec3e35d2d7a56b21cb449d4a7bde8d9d12c2a5Hans Wennborg case FArg: return "F"; 503b8ec3e35d2d7a56b21cb449d4a7bde8d9d12c2a5Hans Wennborg case eArg: return "e"; 504b8ec3e35d2d7a56b21cb449d4a7bde8d9d12c2a5Hans Wennborg case EArg: return "E"; 505b8ec3e35d2d7a56b21cb449d4a7bde8d9d12c2a5Hans Wennborg case gArg: return "g"; 506b8ec3e35d2d7a56b21cb449d4a7bde8d9d12c2a5Hans Wennborg case GArg: return "G"; 507b8ec3e35d2d7a56b21cb449d4a7bde8d9d12c2a5Hans Wennborg case aArg: return "a"; 508b8ec3e35d2d7a56b21cb449d4a7bde8d9d12c2a5Hans Wennborg case AArg: return "A"; 509b8ec3e35d2d7a56b21cb449d4a7bde8d9d12c2a5Hans Wennborg case cArg: return "c"; 510b8ec3e35d2d7a56b21cb449d4a7bde8d9d12c2a5Hans Wennborg case sArg: return "s"; 511b8ec3e35d2d7a56b21cb449d4a7bde8d9d12c2a5Hans Wennborg case pArg: return "p"; 512b8ec3e35d2d7a56b21cb449d4a7bde8d9d12c2a5Hans Wennborg case nArg: return "n"; 513b8ec3e35d2d7a56b21cb449d4a7bde8d9d12c2a5Hans Wennborg case PercentArg: return "%"; 514b8ec3e35d2d7a56b21cb449d4a7bde8d9d12c2a5Hans Wennborg case ScanListArg: return "["; 515b8ec3e35d2d7a56b21cb449d4a7bde8d9d12c2a5Hans Wennborg case InvalidSpecifier: return NULL; 516b8ec3e35d2d7a56b21cb449d4a7bde8d9d12c2a5Hans Wennborg 517b8ec3e35d2d7a56b21cb449d4a7bde8d9d12c2a5Hans Wennborg // MacOS X unicode extensions. 518b8ec3e35d2d7a56b21cb449d4a7bde8d9d12c2a5Hans Wennborg case CArg: return "C"; 519b8ec3e35d2d7a56b21cb449d4a7bde8d9d12c2a5Hans Wennborg case SArg: return "S"; 520b8ec3e35d2d7a56b21cb449d4a7bde8d9d12c2a5Hans Wennborg 521b8ec3e35d2d7a56b21cb449d4a7bde8d9d12c2a5Hans Wennborg // Objective-C specific specifiers. 522b8ec3e35d2d7a56b21cb449d4a7bde8d9d12c2a5Hans Wennborg case ObjCObjArg: return "@"; 523b8ec3e35d2d7a56b21cb449d4a7bde8d9d12c2a5Hans Wennborg 524b8ec3e35d2d7a56b21cb449d4a7bde8d9d12c2a5Hans Wennborg // GlibC specific specifiers. 525b8ec3e35d2d7a56b21cb449d4a7bde8d9d12c2a5Hans Wennborg case PrintErrno: return "m"; 526b8ec3e35d2d7a56b21cb449d4a7bde8d9d12c2a5Hans Wennborg } 527b8ec3e35d2d7a56b21cb449d4a7bde8d9d12c2a5Hans Wennborg return NULL; 528b8ec3e35d2d7a56b21cb449d4a7bde8d9d12c2a5Hans Wennborg} 529b8ec3e35d2d7a56b21cb449d4a7bde8d9d12c2a5Hans Wennborg 530dc84cd5efdd3430efb22546b4ac656aa0540b210David BlaikieOptional<ConversionSpecifier> 531670941c28c0683ecc251dafdf093a71629625dc9Jordan RoseConversionSpecifier::getStandardSpecifier() const { 532670941c28c0683ecc251dafdf093a71629625dc9Jordan Rose ConversionSpecifier::Kind NewKind; 533670941c28c0683ecc251dafdf093a71629625dc9Jordan Rose 534670941c28c0683ecc251dafdf093a71629625dc9Jordan Rose switch (getKind()) { 535670941c28c0683ecc251dafdf093a71629625dc9Jordan Rose default: 53666874fb18afbffb8b2ca05576851a64534be3352David Blaikie return None; 537670941c28c0683ecc251dafdf093a71629625dc9Jordan Rose case DArg: 538670941c28c0683ecc251dafdf093a71629625dc9Jordan Rose NewKind = dArg; 539670941c28c0683ecc251dafdf093a71629625dc9Jordan Rose break; 540670941c28c0683ecc251dafdf093a71629625dc9Jordan Rose case UArg: 541670941c28c0683ecc251dafdf093a71629625dc9Jordan Rose NewKind = uArg; 542670941c28c0683ecc251dafdf093a71629625dc9Jordan Rose break; 543670941c28c0683ecc251dafdf093a71629625dc9Jordan Rose case OArg: 544670941c28c0683ecc251dafdf093a71629625dc9Jordan Rose NewKind = oArg; 545670941c28c0683ecc251dafdf093a71629625dc9Jordan Rose break; 546670941c28c0683ecc251dafdf093a71629625dc9Jordan Rose } 547670941c28c0683ecc251dafdf093a71629625dc9Jordan Rose 548670941c28c0683ecc251dafdf093a71629625dc9Jordan Rose ConversionSpecifier FixedCS(*this); 549670941c28c0683ecc251dafdf093a71629625dc9Jordan Rose FixedCS.setKind(NewKind); 550670941c28c0683ecc251dafdf093a71629625dc9Jordan Rose return FixedCS; 551670941c28c0683ecc251dafdf093a71629625dc9Jordan Rose} 552670941c28c0683ecc251dafdf093a71629625dc9Jordan Rose 553b8ec3e35d2d7a56b21cb449d4a7bde8d9d12c2a5Hans Wennborg//===----------------------------------------------------------------------===// 554826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek// Methods on OptionalAmount. 555826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek//===----------------------------------------------------------------------===// 556826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek 5575f9e272e632e951b1efe824cd16acb4d96077930Chris Lattnervoid OptionalAmount::toString(raw_ostream &os) const { 558826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek switch (hs) { 559826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek case Invalid: 560826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek case NotSpecified: 561826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek return; 562826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek case Arg: 563826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek if (UsesDotPrefix) 564826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek os << "."; 565826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek if (usesPositionalArg()) 566826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek os << "*" << getPositionalArgIndex() << "$"; 567826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek else 568826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek os << "*"; 569826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek break; 570826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek case Constant: 571826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek if (UsesDotPrefix) 572826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek os << "."; 573826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek os << amt; 574826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek break; 575826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek } 576826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek} 577826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek 578bbb6bb4952b77e57b842b4d3096848123ae690e7Jordan Rosebool FormatSpecifier::hasValidLengthModifier(const TargetInfo &Target) const { 579a412a499162c46211c10ad92045b9b5fd2298edeTed Kremenek switch (LM.getKind()) { 580a412a499162c46211c10ad92045b9b5fd2298edeTed Kremenek case LengthModifier::None: 581a412a499162c46211c10ad92045b9b5fd2298edeTed Kremenek return true; 582a412a499162c46211c10ad92045b9b5fd2298edeTed Kremenek 58332addd519c6699000ff79c387a1c87f0ab7c3698Hans Wennborg // Handle most integer flags 584a412a499162c46211c10ad92045b9b5fd2298edeTed Kremenek case LengthModifier::AsChar: 585a412a499162c46211c10ad92045b9b5fd2298edeTed Kremenek case LengthModifier::AsShort: 586a412a499162c46211c10ad92045b9b5fd2298edeTed Kremenek case LengthModifier::AsLongLong: 58732addd519c6699000ff79c387a1c87f0ab7c3698Hans Wennborg case LengthModifier::AsQuad: 588a412a499162c46211c10ad92045b9b5fd2298edeTed Kremenek case LengthModifier::AsIntMax: 589a412a499162c46211c10ad92045b9b5fd2298edeTed Kremenek case LengthModifier::AsSizeT: 590a412a499162c46211c10ad92045b9b5fd2298edeTed Kremenek case LengthModifier::AsPtrDiff: 591a412a499162c46211c10ad92045b9b5fd2298edeTed Kremenek switch (CS.getKind()) { 592a412a499162c46211c10ad92045b9b5fd2298edeTed Kremenek case ConversionSpecifier::dArg: 593275b6f52c7bcafc1f3cf291813b5c60ee776965aJordan Rose case ConversionSpecifier::DArg: 594a412a499162c46211c10ad92045b9b5fd2298edeTed Kremenek case ConversionSpecifier::iArg: 595a412a499162c46211c10ad92045b9b5fd2298edeTed Kremenek case ConversionSpecifier::oArg: 596275b6f52c7bcafc1f3cf291813b5c60ee776965aJordan Rose case ConversionSpecifier::OArg: 597a412a499162c46211c10ad92045b9b5fd2298edeTed Kremenek case ConversionSpecifier::uArg: 598275b6f52c7bcafc1f3cf291813b5c60ee776965aJordan Rose case ConversionSpecifier::UArg: 599a412a499162c46211c10ad92045b9b5fd2298edeTed Kremenek case ConversionSpecifier::xArg: 600a412a499162c46211c10ad92045b9b5fd2298edeTed Kremenek case ConversionSpecifier::XArg: 601a412a499162c46211c10ad92045b9b5fd2298edeTed Kremenek case ConversionSpecifier::nArg: 602a412a499162c46211c10ad92045b9b5fd2298edeTed Kremenek return true; 603a412a499162c46211c10ad92045b9b5fd2298edeTed Kremenek default: 604a412a499162c46211c10ad92045b9b5fd2298edeTed Kremenek return false; 605a412a499162c46211c10ad92045b9b5fd2298edeTed Kremenek } 606a412a499162c46211c10ad92045b9b5fd2298edeTed Kremenek 60732addd519c6699000ff79c387a1c87f0ab7c3698Hans Wennborg // Handle 'l' flag 608a412a499162c46211c10ad92045b9b5fd2298edeTed Kremenek case LengthModifier::AsLong: 609a412a499162c46211c10ad92045b9b5fd2298edeTed Kremenek switch (CS.getKind()) { 610a412a499162c46211c10ad92045b9b5fd2298edeTed Kremenek case ConversionSpecifier::dArg: 611275b6f52c7bcafc1f3cf291813b5c60ee776965aJordan Rose case ConversionSpecifier::DArg: 612a412a499162c46211c10ad92045b9b5fd2298edeTed Kremenek case ConversionSpecifier::iArg: 613a412a499162c46211c10ad92045b9b5fd2298edeTed Kremenek case ConversionSpecifier::oArg: 614275b6f52c7bcafc1f3cf291813b5c60ee776965aJordan Rose case ConversionSpecifier::OArg: 615a412a499162c46211c10ad92045b9b5fd2298edeTed Kremenek case ConversionSpecifier::uArg: 616275b6f52c7bcafc1f3cf291813b5c60ee776965aJordan Rose case ConversionSpecifier::UArg: 617a412a499162c46211c10ad92045b9b5fd2298edeTed Kremenek case ConversionSpecifier::xArg: 618a412a499162c46211c10ad92045b9b5fd2298edeTed Kremenek case ConversionSpecifier::XArg: 619a412a499162c46211c10ad92045b9b5fd2298edeTed Kremenek case ConversionSpecifier::aArg: 620a412a499162c46211c10ad92045b9b5fd2298edeTed Kremenek case ConversionSpecifier::AArg: 621a412a499162c46211c10ad92045b9b5fd2298edeTed Kremenek case ConversionSpecifier::fArg: 622a412a499162c46211c10ad92045b9b5fd2298edeTed Kremenek case ConversionSpecifier::FArg: 623a412a499162c46211c10ad92045b9b5fd2298edeTed Kremenek case ConversionSpecifier::eArg: 624a412a499162c46211c10ad92045b9b5fd2298edeTed Kremenek case ConversionSpecifier::EArg: 625a412a499162c46211c10ad92045b9b5fd2298edeTed Kremenek case ConversionSpecifier::gArg: 626a412a499162c46211c10ad92045b9b5fd2298edeTed Kremenek case ConversionSpecifier::GArg: 627a412a499162c46211c10ad92045b9b5fd2298edeTed Kremenek case ConversionSpecifier::nArg: 628a412a499162c46211c10ad92045b9b5fd2298edeTed Kremenek case ConversionSpecifier::cArg: 629a412a499162c46211c10ad92045b9b5fd2298edeTed Kremenek case ConversionSpecifier::sArg: 630ef1440b6eca118d46291166ce3302f9bba8e639bTed Kremenek case ConversionSpecifier::ScanListArg: 631a412a499162c46211c10ad92045b9b5fd2298edeTed Kremenek return true; 632a412a499162c46211c10ad92045b9b5fd2298edeTed Kremenek default: 633a412a499162c46211c10ad92045b9b5fd2298edeTed Kremenek return false; 634a412a499162c46211c10ad92045b9b5fd2298edeTed Kremenek } 635a412a499162c46211c10ad92045b9b5fd2298edeTed Kremenek 636a412a499162c46211c10ad92045b9b5fd2298edeTed Kremenek case LengthModifier::AsLongDouble: 637a412a499162c46211c10ad92045b9b5fd2298edeTed Kremenek switch (CS.getKind()) { 638a412a499162c46211c10ad92045b9b5fd2298edeTed Kremenek case ConversionSpecifier::aArg: 639a412a499162c46211c10ad92045b9b5fd2298edeTed Kremenek case ConversionSpecifier::AArg: 640a412a499162c46211c10ad92045b9b5fd2298edeTed Kremenek case ConversionSpecifier::fArg: 641a412a499162c46211c10ad92045b9b5fd2298edeTed Kremenek case ConversionSpecifier::FArg: 642a412a499162c46211c10ad92045b9b5fd2298edeTed Kremenek case ConversionSpecifier::eArg: 643a412a499162c46211c10ad92045b9b5fd2298edeTed Kremenek case ConversionSpecifier::EArg: 644a412a499162c46211c10ad92045b9b5fd2298edeTed Kremenek case ConversionSpecifier::gArg: 645a412a499162c46211c10ad92045b9b5fd2298edeTed Kremenek case ConversionSpecifier::GArg: 646a412a499162c46211c10ad92045b9b5fd2298edeTed Kremenek return true; 647bbb6bb4952b77e57b842b4d3096848123ae690e7Jordan Rose // GNU libc extension. 6489d24c2cbd9cf1b7c165ccb13221f2efb2f4b49b0Ted Kremenek case ConversionSpecifier::dArg: 6499d24c2cbd9cf1b7c165ccb13221f2efb2f4b49b0Ted Kremenek case ConversionSpecifier::iArg: 6509d24c2cbd9cf1b7c165ccb13221f2efb2f4b49b0Ted Kremenek case ConversionSpecifier::oArg: 6519d24c2cbd9cf1b7c165ccb13221f2efb2f4b49b0Ted Kremenek case ConversionSpecifier::uArg: 6529d24c2cbd9cf1b7c165ccb13221f2efb2f4b49b0Ted Kremenek case ConversionSpecifier::xArg: 6539d24c2cbd9cf1b7c165ccb13221f2efb2f4b49b0Ted Kremenek case ConversionSpecifier::XArg: 654bbb6bb4952b77e57b842b4d3096848123ae690e7Jordan Rose return !Target.getTriple().isOSDarwin() && 655bbb6bb4952b77e57b842b4d3096848123ae690e7Jordan Rose !Target.getTriple().isOSWindows(); 656a412a499162c46211c10ad92045b9b5fd2298edeTed Kremenek default: 657a412a499162c46211c10ad92045b9b5fd2298edeTed Kremenek return false; 658a412a499162c46211c10ad92045b9b5fd2298edeTed Kremenek } 659d02deebce5f1b283101e035a7f5d5bab0d2068ecHans Wennborg 660d02deebce5f1b283101e035a7f5d5bab0d2068ecHans Wennborg case LengthModifier::AsAllocate: 661d02deebce5f1b283101e035a7f5d5bab0d2068ecHans Wennborg switch (CS.getKind()) { 662d02deebce5f1b283101e035a7f5d5bab0d2068ecHans Wennborg case ConversionSpecifier::sArg: 663d02deebce5f1b283101e035a7f5d5bab0d2068ecHans Wennborg case ConversionSpecifier::SArg: 66428058d179ae40edc66135458849f1073c841bc74Hans Wennborg case ConversionSpecifier::ScanListArg: 665d02deebce5f1b283101e035a7f5d5bab0d2068ecHans Wennborg return true; 666d02deebce5f1b283101e035a7f5d5bab0d2068ecHans Wennborg default: 667d02deebce5f1b283101e035a7f5d5bab0d2068ecHans Wennborg return false; 668d02deebce5f1b283101e035a7f5d5bab0d2068ecHans Wennborg } 66937969b7e14d6a4dfd934ef6d3738cc90b832ec1dHans Wennborg 67037969b7e14d6a4dfd934ef6d3738cc90b832ec1dHans Wennborg case LengthModifier::AsMAllocate: 67137969b7e14d6a4dfd934ef6d3738cc90b832ec1dHans Wennborg switch (CS.getKind()) { 67237969b7e14d6a4dfd934ef6d3738cc90b832ec1dHans Wennborg case ConversionSpecifier::cArg: 67337969b7e14d6a4dfd934ef6d3738cc90b832ec1dHans Wennborg case ConversionSpecifier::CArg: 67437969b7e14d6a4dfd934ef6d3738cc90b832ec1dHans Wennborg case ConversionSpecifier::sArg: 67537969b7e14d6a4dfd934ef6d3738cc90b832ec1dHans Wennborg case ConversionSpecifier::SArg: 67637969b7e14d6a4dfd934ef6d3738cc90b832ec1dHans Wennborg case ConversionSpecifier::ScanListArg: 67737969b7e14d6a4dfd934ef6d3738cc90b832ec1dHans Wennborg return true; 67837969b7e14d6a4dfd934ef6d3738cc90b832ec1dHans Wennborg default: 67937969b7e14d6a4dfd934ef6d3738cc90b832ec1dHans Wennborg return false; 68037969b7e14d6a4dfd934ef6d3738cc90b832ec1dHans Wennborg } 681a412a499162c46211c10ad92045b9b5fd2298edeTed Kremenek } 6823026348bd4c13a0f83b59839f64065e0fcbea253David Blaikie llvm_unreachable("Invalid LengthModifier Kind!"); 683a412a499162c46211c10ad92045b9b5fd2298edeTed Kremenek} 68476517426dc8bf7734c07eefc35171a6bfdba1a2bHans Wennborg 68576517426dc8bf7734c07eefc35171a6bfdba1a2bHans Wennborgbool FormatSpecifier::hasStandardLengthModifier() const { 68676517426dc8bf7734c07eefc35171a6bfdba1a2bHans Wennborg switch (LM.getKind()) { 68776517426dc8bf7734c07eefc35171a6bfdba1a2bHans Wennborg case LengthModifier::None: 68876517426dc8bf7734c07eefc35171a6bfdba1a2bHans Wennborg case LengthModifier::AsChar: 68976517426dc8bf7734c07eefc35171a6bfdba1a2bHans Wennborg case LengthModifier::AsShort: 69076517426dc8bf7734c07eefc35171a6bfdba1a2bHans Wennborg case LengthModifier::AsLong: 69176517426dc8bf7734c07eefc35171a6bfdba1a2bHans Wennborg case LengthModifier::AsLongLong: 69276517426dc8bf7734c07eefc35171a6bfdba1a2bHans Wennborg case LengthModifier::AsIntMax: 69376517426dc8bf7734c07eefc35171a6bfdba1a2bHans Wennborg case LengthModifier::AsSizeT: 69476517426dc8bf7734c07eefc35171a6bfdba1a2bHans Wennborg case LengthModifier::AsPtrDiff: 69576517426dc8bf7734c07eefc35171a6bfdba1a2bHans Wennborg case LengthModifier::AsLongDouble: 69676517426dc8bf7734c07eefc35171a6bfdba1a2bHans Wennborg return true; 69776517426dc8bf7734c07eefc35171a6bfdba1a2bHans Wennborg case LengthModifier::AsAllocate: 69876517426dc8bf7734c07eefc35171a6bfdba1a2bHans Wennborg case LengthModifier::AsMAllocate: 69976517426dc8bf7734c07eefc35171a6bfdba1a2bHans Wennborg case LengthModifier::AsQuad: 70076517426dc8bf7734c07eefc35171a6bfdba1a2bHans Wennborg return false; 70176517426dc8bf7734c07eefc35171a6bfdba1a2bHans Wennborg } 70276517426dc8bf7734c07eefc35171a6bfdba1a2bHans Wennborg llvm_unreachable("Invalid LengthModifier Kind!"); 70376517426dc8bf7734c07eefc35171a6bfdba1a2bHans Wennborg} 70476517426dc8bf7734c07eefc35171a6bfdba1a2bHans Wennborg 70576517426dc8bf7734c07eefc35171a6bfdba1a2bHans Wennborgbool FormatSpecifier::hasStandardConversionSpecifier(const LangOptions &LangOpt) const { 70676517426dc8bf7734c07eefc35171a6bfdba1a2bHans Wennborg switch (CS.getKind()) { 70776517426dc8bf7734c07eefc35171a6bfdba1a2bHans Wennborg case ConversionSpecifier::cArg: 70876517426dc8bf7734c07eefc35171a6bfdba1a2bHans Wennborg case ConversionSpecifier::dArg: 70976517426dc8bf7734c07eefc35171a6bfdba1a2bHans Wennborg case ConversionSpecifier::iArg: 71076517426dc8bf7734c07eefc35171a6bfdba1a2bHans Wennborg case ConversionSpecifier::oArg: 71176517426dc8bf7734c07eefc35171a6bfdba1a2bHans Wennborg case ConversionSpecifier::uArg: 71276517426dc8bf7734c07eefc35171a6bfdba1a2bHans Wennborg case ConversionSpecifier::xArg: 71376517426dc8bf7734c07eefc35171a6bfdba1a2bHans Wennborg case ConversionSpecifier::XArg: 71476517426dc8bf7734c07eefc35171a6bfdba1a2bHans Wennborg case ConversionSpecifier::fArg: 71576517426dc8bf7734c07eefc35171a6bfdba1a2bHans Wennborg case ConversionSpecifier::FArg: 71676517426dc8bf7734c07eefc35171a6bfdba1a2bHans Wennborg case ConversionSpecifier::eArg: 71776517426dc8bf7734c07eefc35171a6bfdba1a2bHans Wennborg case ConversionSpecifier::EArg: 71876517426dc8bf7734c07eefc35171a6bfdba1a2bHans Wennborg case ConversionSpecifier::gArg: 71976517426dc8bf7734c07eefc35171a6bfdba1a2bHans Wennborg case ConversionSpecifier::GArg: 72076517426dc8bf7734c07eefc35171a6bfdba1a2bHans Wennborg case ConversionSpecifier::aArg: 72176517426dc8bf7734c07eefc35171a6bfdba1a2bHans Wennborg case ConversionSpecifier::AArg: 72276517426dc8bf7734c07eefc35171a6bfdba1a2bHans Wennborg case ConversionSpecifier::sArg: 72376517426dc8bf7734c07eefc35171a6bfdba1a2bHans Wennborg case ConversionSpecifier::pArg: 72476517426dc8bf7734c07eefc35171a6bfdba1a2bHans Wennborg case ConversionSpecifier::nArg: 72576517426dc8bf7734c07eefc35171a6bfdba1a2bHans Wennborg case ConversionSpecifier::ObjCObjArg: 72676517426dc8bf7734c07eefc35171a6bfdba1a2bHans Wennborg case ConversionSpecifier::ScanListArg: 72776517426dc8bf7734c07eefc35171a6bfdba1a2bHans Wennborg case ConversionSpecifier::PercentArg: 72876517426dc8bf7734c07eefc35171a6bfdba1a2bHans Wennborg return true; 72976517426dc8bf7734c07eefc35171a6bfdba1a2bHans Wennborg case ConversionSpecifier::CArg: 73076517426dc8bf7734c07eefc35171a6bfdba1a2bHans Wennborg case ConversionSpecifier::SArg: 73176517426dc8bf7734c07eefc35171a6bfdba1a2bHans Wennborg return LangOpt.ObjC1 || LangOpt.ObjC2; 73276517426dc8bf7734c07eefc35171a6bfdba1a2bHans Wennborg case ConversionSpecifier::InvalidSpecifier: 73376517426dc8bf7734c07eefc35171a6bfdba1a2bHans Wennborg case ConversionSpecifier::PrintErrno: 734275b6f52c7bcafc1f3cf291813b5c60ee776965aJordan Rose case ConversionSpecifier::DArg: 735275b6f52c7bcafc1f3cf291813b5c60ee776965aJordan Rose case ConversionSpecifier::OArg: 736275b6f52c7bcafc1f3cf291813b5c60ee776965aJordan Rose case ConversionSpecifier::UArg: 73776517426dc8bf7734c07eefc35171a6bfdba1a2bHans Wennborg return false; 73876517426dc8bf7734c07eefc35171a6bfdba1a2bHans Wennborg } 73976517426dc8bf7734c07eefc35171a6bfdba1a2bHans Wennborg llvm_unreachable("Invalid ConversionSpecifier Kind!"); 74076517426dc8bf7734c07eefc35171a6bfdba1a2bHans Wennborg} 74176517426dc8bf7734c07eefc35171a6bfdba1a2bHans Wennborg 74276517426dc8bf7734c07eefc35171a6bfdba1a2bHans Wennborgbool FormatSpecifier::hasStandardLengthConversionCombination() const { 74376517426dc8bf7734c07eefc35171a6bfdba1a2bHans Wennborg if (LM.getKind() == LengthModifier::AsLongDouble) { 74476517426dc8bf7734c07eefc35171a6bfdba1a2bHans Wennborg switch(CS.getKind()) { 74576517426dc8bf7734c07eefc35171a6bfdba1a2bHans Wennborg case ConversionSpecifier::dArg: 74676517426dc8bf7734c07eefc35171a6bfdba1a2bHans Wennborg case ConversionSpecifier::iArg: 74776517426dc8bf7734c07eefc35171a6bfdba1a2bHans Wennborg case ConversionSpecifier::oArg: 74876517426dc8bf7734c07eefc35171a6bfdba1a2bHans Wennborg case ConversionSpecifier::uArg: 74976517426dc8bf7734c07eefc35171a6bfdba1a2bHans Wennborg case ConversionSpecifier::xArg: 75076517426dc8bf7734c07eefc35171a6bfdba1a2bHans Wennborg case ConversionSpecifier::XArg: 75176517426dc8bf7734c07eefc35171a6bfdba1a2bHans Wennborg return false; 75276517426dc8bf7734c07eefc35171a6bfdba1a2bHans Wennborg default: 75376517426dc8bf7734c07eefc35171a6bfdba1a2bHans Wennborg return true; 75476517426dc8bf7734c07eefc35171a6bfdba1a2bHans Wennborg } 75576517426dc8bf7734c07eefc35171a6bfdba1a2bHans Wennborg } 75676517426dc8bf7734c07eefc35171a6bfdba1a2bHans Wennborg return true; 75776517426dc8bf7734c07eefc35171a6bfdba1a2bHans Wennborg} 7584684778993c667246039b4664acbce59dc99440cHans Wennborg 759dc84cd5efdd3430efb22546b4ac656aa0540b210David BlaikieOptional<LengthModifier> FormatSpecifier::getCorrectedLengthModifier() const { 7608be066e6733364cd34f25c4f7b7344f72aa23369Jordan Rose if (CS.isAnyIntArg() || CS.getKind() == ConversionSpecifier::nArg) { 7618be066e6733364cd34f25c4f7b7344f72aa23369Jordan Rose if (LM.getKind() == LengthModifier::AsLongDouble || 7628be066e6733364cd34f25c4f7b7344f72aa23369Jordan Rose LM.getKind() == LengthModifier::AsQuad) { 763bbb6bb4952b77e57b842b4d3096848123ae690e7Jordan Rose LengthModifier FixedLM(LM); 764bbb6bb4952b77e57b842b4d3096848123ae690e7Jordan Rose FixedLM.setKind(LengthModifier::AsLongLong); 765bbb6bb4952b77e57b842b4d3096848123ae690e7Jordan Rose return FixedLM; 766bbb6bb4952b77e57b842b4d3096848123ae690e7Jordan Rose } 767bbb6bb4952b77e57b842b4d3096848123ae690e7Jordan Rose } 768bbb6bb4952b77e57b842b4d3096848123ae690e7Jordan Rose 76966874fb18afbffb8b2ca05576851a64534be3352David Blaikie return None; 770bbb6bb4952b77e57b842b4d3096848123ae690e7Jordan Rose} 771bbb6bb4952b77e57b842b4d3096848123ae690e7Jordan Rose 7724684778993c667246039b4664acbce59dc99440cHans Wennborgbool FormatSpecifier::namedTypeToLengthModifier(QualType QT, 7734684778993c667246039b4664acbce59dc99440cHans Wennborg LengthModifier &LM) { 7744684778993c667246039b4664acbce59dc99440cHans Wennborg assert(isa<TypedefType>(QT) && "Expected a TypedefType"); 7754684778993c667246039b4664acbce59dc99440cHans Wennborg const TypedefNameDecl *Typedef = cast<TypedefType>(QT)->getDecl(); 7764684778993c667246039b4664acbce59dc99440cHans Wennborg 7774684778993c667246039b4664acbce59dc99440cHans Wennborg for (;;) { 7784684778993c667246039b4664acbce59dc99440cHans Wennborg const IdentifierInfo *Identifier = Typedef->getIdentifier(); 7794684778993c667246039b4664acbce59dc99440cHans Wennborg if (Identifier->getName() == "size_t") { 7804684778993c667246039b4664acbce59dc99440cHans Wennborg LM.setKind(LengthModifier::AsSizeT); 7814684778993c667246039b4664acbce59dc99440cHans Wennborg return true; 7824684778993c667246039b4664acbce59dc99440cHans Wennborg } else if (Identifier->getName() == "ssize_t") { 7834684778993c667246039b4664acbce59dc99440cHans Wennborg // Not C99, but common in Unix. 7844684778993c667246039b4664acbce59dc99440cHans Wennborg LM.setKind(LengthModifier::AsSizeT); 7854684778993c667246039b4664acbce59dc99440cHans Wennborg return true; 7864684778993c667246039b4664acbce59dc99440cHans Wennborg } else if (Identifier->getName() == "intmax_t") { 7874684778993c667246039b4664acbce59dc99440cHans Wennborg LM.setKind(LengthModifier::AsIntMax); 7884684778993c667246039b4664acbce59dc99440cHans Wennborg return true; 7894684778993c667246039b4664acbce59dc99440cHans Wennborg } else if (Identifier->getName() == "uintmax_t") { 7904684778993c667246039b4664acbce59dc99440cHans Wennborg LM.setKind(LengthModifier::AsIntMax); 7914684778993c667246039b4664acbce59dc99440cHans Wennborg return true; 7924684778993c667246039b4664acbce59dc99440cHans Wennborg } else if (Identifier->getName() == "ptrdiff_t") { 7934684778993c667246039b4664acbce59dc99440cHans Wennborg LM.setKind(LengthModifier::AsPtrDiff); 7944684778993c667246039b4664acbce59dc99440cHans Wennborg return true; 7954684778993c667246039b4664acbce59dc99440cHans Wennborg } 7964684778993c667246039b4664acbce59dc99440cHans Wennborg 7974684778993c667246039b4664acbce59dc99440cHans Wennborg QualType T = Typedef->getUnderlyingType(); 7984684778993c667246039b4664acbce59dc99440cHans Wennborg if (!isa<TypedefType>(T)) 7994684778993c667246039b4664acbce59dc99440cHans Wennborg break; 8004684778993c667246039b4664acbce59dc99440cHans Wennborg 8014684778993c667246039b4664acbce59dc99440cHans Wennborg Typedef = cast<TypedefType>(T)->getDecl(); 8024684778993c667246039b4664acbce59dc99440cHans Wennborg } 8034684778993c667246039b4664acbce59dc99440cHans Wennborg return false; 8044684778993c667246039b4664acbce59dc99440cHans Wennborg} 805