FormatString.cpp revision f3749f4168c5cee59627a681ca4ca6e4116d0761
1e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera// FormatString.cpp - Common stuff for handling printf/scanf formats -*- C++ -*- 2e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera// 3e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera// The LLVM Compiler Infrastructure 4e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera// 5e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera// This file is distributed under the University of Illinois Open Source 6e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera// License. See LICENSE.TXT for details. 7e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera// 8e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera//===----------------------------------------------------------------------===// 9e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera// 10e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera// Shared details for processing format strings of printf and scanf 11e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera// (and friends). 12e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera// 13e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera//===----------------------------------------------------------------------===// 14e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera 15e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera#include "FormatStringParsing.h" 16e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera#include "clang/Basic/LangOptions.h" 17e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera 18e229751d11692ede7fed3b56472f2d020767b412Ricardo Cerverausing clang::analyze_format_string::ArgType; 19e229751d11692ede7fed3b56472f2d020767b412Ricardo Cerverausing clang::analyze_format_string::FormatStringHandler; 20e229751d11692ede7fed3b56472f2d020767b412Ricardo Cerverausing clang::analyze_format_string::FormatSpecifier; 21e229751d11692ede7fed3b56472f2d020767b412Ricardo Cerverausing clang::analyze_format_string::LengthModifier; 22e229751d11692ede7fed3b56472f2d020767b412Ricardo Cerverausing clang::analyze_format_string::OptionalAmount; 23e229751d11692ede7fed3b56472f2d020767b412Ricardo Cerverausing clang::analyze_format_string::PositionContext; 24e229751d11692ede7fed3b56472f2d020767b412Ricardo Cerverausing clang::analyze_format_string::ConversionSpecifier; 25e229751d11692ede7fed3b56472f2d020767b412Ricardo Cerverausing namespace clang; 26e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera 27e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera// Key function to FormatStringHandler. 28e229751d11692ede7fed3b56472f2d020767b412Ricardo CerveraFormatStringHandler::~FormatStringHandler() {} 29e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera 30e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera//===----------------------------------------------------------------------===// 31e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera// Functions for parsing format strings components in both printf and 32e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera// scanf format strings. 33e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera//===----------------------------------------------------------------------===// 34e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera 35e229751d11692ede7fed3b56472f2d020767b412Ricardo CerveraOptionalAmount 36e229751d11692ede7fed3b56472f2d020767b412Ricardo Cerveraclang::analyze_format_string::ParseAmount(const char *&Beg, const char *E) { 37e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera const char *I = Beg; 38e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera UpdateOnReturn <const char*> UpdateBeg(Beg, I); 39e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera 40e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera unsigned accumulator = 0; 41e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera bool hasDigits = false; 42e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera 43e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera for ( ; I != E; ++I) { 44e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera char c = *I; 45e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera if (c >= '0' && c <= '9') { 46e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera hasDigits = true; 47e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera accumulator = (accumulator * 10) + (c - '0'); 48e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera continue; 49e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera } 50e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera 51e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera if (hasDigits) 52e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera return OptionalAmount(OptionalAmount::Constant, accumulator, Beg, I - Beg, 53e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera false); 54e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera 55e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera break; 56e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera } 57e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera 58e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera return OptionalAmount(); 59e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera} 60e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera 61e229751d11692ede7fed3b56472f2d020767b412Ricardo CerveraOptionalAmount 62e229751d11692ede7fed3b56472f2d020767b412Ricardo Cerveraclang::analyze_format_string::ParseNonPositionAmount(const char *&Beg, 63e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera const char *E, 64e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera unsigned &argIndex) { 65e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera if (*Beg == '*') { 66e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera ++Beg; 67e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera return OptionalAmount(OptionalAmount::Arg, argIndex++, Beg, 0, false); 68e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera } 69e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera 70e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera return ParseAmount(Beg, E); 71e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera} 72e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera 73e229751d11692ede7fed3b56472f2d020767b412Ricardo CerveraOptionalAmount 74e229751d11692ede7fed3b56472f2d020767b412Ricardo Cerveraclang::analyze_format_string::ParsePositionAmount(FormatStringHandler &H, 75e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera const char *Start, 76e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera const char *&Beg, 77e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera const char *E, 78e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera PositionContext p) { 79e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera if (*Beg == '*') { 80e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera const char *I = Beg + 1; 81e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera const OptionalAmount &Amt = ParseAmount(I, E); 82e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera 83e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera if (Amt.getHowSpecified() == OptionalAmount::NotSpecified) { 84e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera H.HandleInvalidPosition(Beg, I - Beg, p); 85e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera return OptionalAmount(false); 86e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera } 87e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera 88e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera if (I == E) { 89e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera // No more characters left? 90e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera H.HandleIncompleteSpecifier(Start, E - Start); 91e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera return OptionalAmount(false); 92e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera } 93e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera 94e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera assert(Amt.getHowSpecified() == OptionalAmount::Constant); 95e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera 96e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera if (*I == '$') { 97e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera // Handle positional arguments 98e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera 99e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera // Special case: '*0$', since this is an easy mistake. 100e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera if (Amt.getConstantAmount() == 0) { 101e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera H.HandleZeroPosition(Beg, I - Beg + 1); 102e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera return OptionalAmount(false); 103e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera } 104e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera 105e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera const char *Tmp = Beg; 106e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera Beg = ++I; 107e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera 108e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera return OptionalAmount(OptionalAmount::Arg, Amt.getConstantAmount() - 1, 109e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera Tmp, 0, true); 110e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera } 111e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera 112e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera H.HandleInvalidPosition(Beg, I - Beg, p); 113e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera return OptionalAmount(false); 114e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera } 115e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera 116e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera return ParseAmount(Beg, E); 117e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera} 118e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera 119e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera 120e229751d11692ede7fed3b56472f2d020767b412Ricardo Cerverabool 121e229751d11692ede7fed3b56472f2d020767b412Ricardo Cerveraclang::analyze_format_string::ParseFieldWidth(FormatStringHandler &H, 122e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera FormatSpecifier &CS, 123e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera const char *Start, 124e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera const char *&Beg, const char *E, 125e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera unsigned *argIndex) { 126e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera // FIXME: Support negative field widths. 127e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera if (argIndex) { 128e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera CS.setFieldWidth(ParseNonPositionAmount(Beg, E, *argIndex)); 129e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera } 130e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera else { 131e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera const OptionalAmount Amt = 132e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera ParsePositionAmount(H, Start, Beg, E, 133e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera analyze_format_string::FieldWidthPos); 134e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera 135e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera if (Amt.isInvalid()) 136e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera return true; 137e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera CS.setFieldWidth(Amt); 138e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera } 139e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera return false; 140e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera} 141e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera 142e229751d11692ede7fed3b56472f2d020767b412Ricardo Cerverabool 143e229751d11692ede7fed3b56472f2d020767b412Ricardo Cerveraclang::analyze_format_string::ParseArgPosition(FormatStringHandler &H, 144e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera FormatSpecifier &FS, 145e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera const char *Start, 146e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera const char *&Beg, 147e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera const char *E) { 148e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera const char *I = Beg; 149e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera 150e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera const OptionalAmount &Amt = ParseAmount(I, E); 151e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera 152e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera if (I == E) { 153e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera // No more characters left? 154e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera H.HandleIncompleteSpecifier(Start, E - Start); 155e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera return true; 156e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera } 157e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera 158e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera if (Amt.getHowSpecified() == OptionalAmount::Constant && *(I++) == '$') { 159e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera // Warn that positional arguments are non-standard. 160e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera H.HandlePosition(Start, I - Start); 161e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera 162e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera // Special case: '%0$', since this is an easy mistake. 163e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera if (Amt.getConstantAmount() == 0) { 164e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera H.HandleZeroPosition(Start, I - Start); 165e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera return true; 166e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera } 167e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera 168e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera FS.setArgIndex(Amt.getConstantAmount() - 1); 169e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera FS.setUsesPositionalArg(); 170e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera // Update the caller's pointer if we decided to consume 171e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera // these characters. 172e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera Beg = I; 173e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera return false; 174e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera } 175e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera 176e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera return false; 177e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera} 178e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera 179e229751d11692ede7fed3b56472f2d020767b412Ricardo Cerverabool 180e229751d11692ede7fed3b56472f2d020767b412Ricardo Cerveraclang::analyze_format_string::ParseLengthModifier(FormatSpecifier &FS, 181e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera const char *&I, 182e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera const char *E, 183e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera const LangOptions &LO, 184e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera bool IsScanf) { 185e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera LengthModifier::Kind lmKind = LengthModifier::None; 186e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera const char *lmPosition = I; 187e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera switch (*I) { 188e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera default: 189e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera return false; 190e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera case 'h': 191e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera ++I; 192e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera lmKind = (I != E && *I == 'h') ? (++I, LengthModifier::AsChar) 193e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera : LengthModifier::AsShort; 194e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera break; 195e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera case 'l': 196e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera ++I; 197e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera lmKind = (I != E && *I == 'l') ? (++I, LengthModifier::AsLongLong) 198e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera : LengthModifier::AsLong; 199e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera break; 200e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera case 'j': lmKind = LengthModifier::AsIntMax; ++I; break; 201e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera case 'z': lmKind = LengthModifier::AsSizeT; ++I; break; 202e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera case 't': lmKind = LengthModifier::AsPtrDiff; ++I; break; 203e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera case 'L': lmKind = LengthModifier::AsLongDouble; ++I; break; 204e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera case 'q': lmKind = LengthModifier::AsQuad; ++I; break; 205e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera case 'a': 206e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera if (IsScanf && !LO.C99 && !LO.CPlusPlus0x) { 207e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera // For scanf in C90, look at the next character to see if this should 208e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera // be parsed as the GNU extension 'a' length modifier. If not, this 209e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera // will be parsed as a conversion specifier. 210e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera ++I; 211e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera if (I != E && (*I == 's' || *I == 'S' || *I == '[')) { 212e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera lmKind = LengthModifier::AsAllocate; 213e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera break; 214e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera } 215e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera --I; 216e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera } 217e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera return false; 218e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera case 'm': 219e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera if (IsScanf) { 220e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera lmKind = LengthModifier::AsMAllocate; 221e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera ++I; 222e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera break; 223e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera } 224e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera return false; 225e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera } 226e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera LengthModifier lm(lmPosition, lmKind); 227e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera FS.setLengthModifier(lm); 228e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera return true; 229e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera} 230e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera 231e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera//===----------------------------------------------------------------------===// 232e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera// Methods on ArgType. 233e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera//===----------------------------------------------------------------------===// 234e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera 235e229751d11692ede7fed3b56472f2d020767b412Ricardo Cerverabool ArgType::matchesType(ASTContext &C, QualType argTy) const { 236e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera switch (K) { 237e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera case InvalidTy: 238e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera llvm_unreachable("ArgType must be valid"); 239e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera 240e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera case UnknownTy: 241e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera return true; 242e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera 243e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera case AnyCharTy: { 244e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera if (const EnumType *ETy = argTy->getAs<EnumType>()) 245e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera argTy = ETy->getDecl()->getIntegerType(); 246e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera 247e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera if (const BuiltinType *BT = argTy->getAs<BuiltinType>()) 248e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera switch (BT->getKind()) { 249e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera default: 250e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera break; 251e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera case BuiltinType::Char_S: 252e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera case BuiltinType::SChar: 253e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera case BuiltinType::UChar: 254e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera case BuiltinType::Char_U: 255e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera return true; 256e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera } 257e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera return false; 258e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera } 259e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera 260e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera case SpecificTy: { 261e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera if (const EnumType *ETy = argTy->getAs<EnumType>()) 262e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera argTy = ETy->getDecl()->getIntegerType(); 263e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera argTy = C.getCanonicalType(argTy).getUnqualifiedType(); 264e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera 265e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera if (const PointerType *PTy = argTy->getAs<PointerType>()) { 266e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera // Strip volatile qualifier from pointee type. 267e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera QualType Pointee = PTy->getPointeeType(); 268e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera Pointee.removeLocalVolatile(); 269e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera argTy = C.getPointerType(Pointee); 270e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera } 271e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera 272e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera if (T == argTy) 273e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera return true; 274e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera // Check for "compatible types". 275e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera if (const BuiltinType *BT = argTy->getAs<BuiltinType>()) 276e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera switch (BT->getKind()) { 277e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera default: 278e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera break; 279e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera case BuiltinType::Char_S: 280e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera case BuiltinType::SChar: 281e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera case BuiltinType::Char_U: 282e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera case BuiltinType::UChar: 283e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera return T == C.UnsignedCharTy || T == C.SignedCharTy; 284e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera case BuiltinType::Short: 285e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera return T == C.UnsignedShortTy; 286e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera case BuiltinType::UShort: 287e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera return T == C.ShortTy; 288e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera case BuiltinType::Int: 289e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera return T == C.UnsignedIntTy; 290e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera case BuiltinType::UInt: 291e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera return T == C.IntTy; 292e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera case BuiltinType::Long: 293e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera return T == C.UnsignedLongTy; 294e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera case BuiltinType::ULong: 295e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera return T == C.LongTy; 296e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera case BuiltinType::LongLong: 297e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera return T == C.UnsignedLongLongTy; 298e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera case BuiltinType::ULongLong: 299e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera return T == C.LongLongTy; 300e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera } 301e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera return false; 302e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera } 303e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera 304e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera case CStrTy: { 305e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera const PointerType *PT = argTy->getAs<PointerType>(); 306e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera if (!PT) 307e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera return false; 308e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera QualType pointeeTy = PT->getPointeeType(); 309e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera if (const BuiltinType *BT = pointeeTy->getAs<BuiltinType>()) 310e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera switch (BT->getKind()) { 311e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera case BuiltinType::Void: 312e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera case BuiltinType::Char_U: 313e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera case BuiltinType::UChar: 314e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera case BuiltinType::Char_S: 315e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera case BuiltinType::SChar: 316e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera return true; 317e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera default: 318e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera break; 319e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera } 320e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera 321e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera return false; 322e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera } 323e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera 324e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera case WCStrTy: { 325e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera const PointerType *PT = argTy->getAs<PointerType>(); 326e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera if (!PT) 327e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera return false; 328e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera QualType pointeeTy = 329e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera C.getCanonicalType(PT->getPointeeType()).getUnqualifiedType(); 330e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera return pointeeTy == C.getWCharType(); 331e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera } 332e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera 333e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera case WIntTy: { 334e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera 335e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera QualType PromoArg = 336e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera argTy->isPromotableIntegerType() 337e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera ? C.getPromotedIntegerType(argTy) : argTy; 338e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera 339e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera QualType WInt = C.getCanonicalType(C.getWIntType()).getUnqualifiedType(); 340e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera PromoArg = C.getCanonicalType(PromoArg).getUnqualifiedType(); 341e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera 342e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera // If the promoted argument is the corresponding signed type of the 343e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera // wint_t type, then it should match. 344e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera if (PromoArg->hasSignedIntegerRepresentation() && 345e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera C.getCorrespondingUnsignedType(PromoArg) == WInt) 346e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera return true; 347e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera 348e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera return WInt == PromoArg; 349e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera } 350e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera 351e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera case CPointerTy: 352e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera return argTy->isPointerType() || argTy->isObjCObjectPointerType() || 353e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera argTy->isBlockPointerType() || argTy->isNullPtrType(); 354e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera 355e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera case ObjCPointerTy: { 356e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera if (argTy->getAs<ObjCObjectPointerType>() || 357e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera argTy->getAs<BlockPointerType>()) 358e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera return true; 359e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera 360e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera // Handle implicit toll-free bridging. 361e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera if (const PointerType *PT = argTy->getAs<PointerType>()) { 362e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera // Things such as CFTypeRef are really just opaque pointers 363e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera // to C structs representing CF types that can often be bridged 364e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera // to Objective-C objects. Since the compiler doesn't know which 365e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera // structs can be toll-free bridged, we just accept them all. 366e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera QualType pointee = PT->getPointeeType(); 367e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera if (pointee->getAsStructureType() || pointee->isVoidType()) 368e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera return true; 369e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera } 370e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera return false; 371e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera } 372e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera } 373e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera 374e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera llvm_unreachable("Invalid ArgType Kind!"); 375e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera} 376e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera 377e229751d11692ede7fed3b56472f2d020767b412Ricardo CerveraQualType ArgType::getRepresentativeType(ASTContext &C) const { 378e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera switch (K) { 379e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera case InvalidTy: 380e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera llvm_unreachable("No representative type for Invalid ArgType"); 381e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera case UnknownTy: 382e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera return QualType(); 383e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera case AnyCharTy: 384e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera return C.CharTy; 385e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera case SpecificTy: 386e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera return T; 387e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera case CStrTy: 388e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera return C.getPointerType(C.CharTy); 389e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera case WCStrTy: 390e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera return C.getPointerType(C.getWCharType()); 391e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera case ObjCPointerTy: 392e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera return C.ObjCBuiltinIdTy; 393e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera case CPointerTy: 394e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera return C.VoidPtrTy; 395e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera case WIntTy: { 396e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera return C.getWIntType(); 397e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera } 398e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera } 399e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera 400e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera llvm_unreachable("Invalid ArgType Kind!"); 401e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera} 402e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera 403e229751d11692ede7fed3b56472f2d020767b412Ricardo Cerverastd::string ArgType::getRepresentativeTypeName(ASTContext &C) const { 404e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera std::string S = getRepresentativeType(C).getAsString(); 405e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera if (Name && S != Name) 406e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera return std::string("'") + Name + "' (aka '" + S + "')"; 407e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera return std::string("'") + S + "'"; 408e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera} 409e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera 410e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera 411e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera//===----------------------------------------------------------------------===// 412e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera// Methods on OptionalAmount. 413e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera//===----------------------------------------------------------------------===// 414e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera 415e229751d11692ede7fed3b56472f2d020767b412Ricardo CerveraArgType 416e229751d11692ede7fed3b56472f2d020767b412Ricardo Cerveraanalyze_format_string::OptionalAmount::getArgType(ASTContext &Ctx) const { 417e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera return Ctx.IntTy; 418e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera} 419e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera 420e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera//===----------------------------------------------------------------------===// 421e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera// Methods on LengthModifier. 422e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera//===----------------------------------------------------------------------===// 423e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera 424e229751d11692ede7fed3b56472f2d020767b412Ricardo Cerveraconst char * 425e229751d11692ede7fed3b56472f2d020767b412Ricardo Cerveraanalyze_format_string::LengthModifier::toString() const { 426e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera switch (kind) { 427e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera case AsChar: 428e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera return "hh"; 429e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera case AsShort: 430e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera return "h"; 431e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera case AsLong: // or AsWideChar 432e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera return "l"; 433e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera case AsLongLong: 434e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera return "ll"; 435e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera case AsQuad: 436e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera return "q"; 437e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera case AsIntMax: 438e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera return "j"; 439e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera case AsSizeT: 440e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera return "z"; 441e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera case AsPtrDiff: 442e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera return "t"; 443e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera case AsLongDouble: 444e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera return "L"; 445e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera case AsAllocate: 446e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera return "a"; 447e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera case AsMAllocate: 448e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera return "m"; 449e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera case None: 450e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera return ""; 451e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera } 452e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera return NULL; 453e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera} 454e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera 455e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera//===----------------------------------------------------------------------===// 456e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera// Methods on ConversionSpecifier. 457e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera//===----------------------------------------------------------------------===// 458e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera 459e229751d11692ede7fed3b56472f2d020767b412Ricardo Cerveraconst char *ConversionSpecifier::toString() const { 460e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera switch (kind) { 461e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera case dArg: return "d"; 462e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera case iArg: return "i"; 463e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera case oArg: return "o"; 464e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera case uArg: return "u"; 465e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera case xArg: return "x"; 466e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera case XArg: return "X"; 467e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera case fArg: return "f"; 468e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera case FArg: return "F"; 469e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera case eArg: return "e"; 470e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera case EArg: return "E"; 471e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera case gArg: return "g"; 472e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera case GArg: return "G"; 473e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera case aArg: return "a"; 474e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera case AArg: return "A"; 475e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera case cArg: return "c"; 476e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera case sArg: return "s"; 477e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera case pArg: return "p"; 478e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera case nArg: return "n"; 479e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera case PercentArg: return "%"; 480e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera case ScanListArg: return "["; 481e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera case InvalidSpecifier: return NULL; 482e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera 483e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera // MacOS X unicode extensions. 484e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera case CArg: return "C"; 485e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera case SArg: return "S"; 486e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera 487e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera // Objective-C specific specifiers. 488e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera case ObjCObjArg: return "@"; 489e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera 490e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera // GlibC specific specifiers. 491e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera case PrintErrno: return "m"; 492e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera } 493e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera return NULL; 494e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera} 495e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera 496e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera//===----------------------------------------------------------------------===// 497e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera// Methods on OptionalAmount. 498e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera//===----------------------------------------------------------------------===// 499e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera 500e229751d11692ede7fed3b56472f2d020767b412Ricardo Cerveravoid OptionalAmount::toString(raw_ostream &os) const { 501e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera switch (hs) { 502e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera case Invalid: 503e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera case NotSpecified: 504e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera return; 505e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera case Arg: 506e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera if (UsesDotPrefix) 507e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera os << "."; 508e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera if (usesPositionalArg()) 509e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera os << "*" << getPositionalArgIndex() << "$"; 510e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera else 511e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera os << "*"; 512e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera break; 513e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera case Constant: 514e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera if (UsesDotPrefix) 515e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera os << "."; 516e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera os << amt; 517e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera break; 518e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera } 519e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera} 520e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera 521e229751d11692ede7fed3b56472f2d020767b412Ricardo Cerverabool FormatSpecifier::hasValidLengthModifier() const { 522e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera switch (LM.getKind()) { 523e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera case LengthModifier::None: 524e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera return true; 525e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera 526e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera // Handle most integer flags 527e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera case LengthModifier::AsChar: 528e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera case LengthModifier::AsShort: 529e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera case LengthModifier::AsLongLong: 530e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera case LengthModifier::AsQuad: 531e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera case LengthModifier::AsIntMax: 532e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera case LengthModifier::AsSizeT: 533e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera case LengthModifier::AsPtrDiff: 534e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera switch (CS.getKind()) { 535e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera case ConversionSpecifier::dArg: 536e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera case ConversionSpecifier::iArg: 537e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera case ConversionSpecifier::oArg: 538e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera case ConversionSpecifier::uArg: 539e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera case ConversionSpecifier::xArg: 540e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera case ConversionSpecifier::XArg: 541e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera case ConversionSpecifier::nArg: 542e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera return true; 543e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera default: 544e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera return false; 545e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera } 546e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera 547e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera // Handle 'l' flag 548e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera case LengthModifier::AsLong: 549e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera switch (CS.getKind()) { 550e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera case ConversionSpecifier::dArg: 551e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera case ConversionSpecifier::iArg: 552e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera case ConversionSpecifier::oArg: 553e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera case ConversionSpecifier::uArg: 554e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera case ConversionSpecifier::xArg: 555e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera case ConversionSpecifier::XArg: 556e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera case ConversionSpecifier::aArg: 557e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera case ConversionSpecifier::AArg: 558e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera case ConversionSpecifier::fArg: 559e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera case ConversionSpecifier::FArg: 560e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera case ConversionSpecifier::eArg: 561e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera case ConversionSpecifier::EArg: 562e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera case ConversionSpecifier::gArg: 563e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera case ConversionSpecifier::GArg: 564e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera case ConversionSpecifier::nArg: 565e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera case ConversionSpecifier::cArg: 566e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera case ConversionSpecifier::sArg: 567e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera case ConversionSpecifier::ScanListArg: 568e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera return true; 569e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera default: 570e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera return false; 571e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera } 572e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera 573e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera case LengthModifier::AsLongDouble: 574e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera switch (CS.getKind()) { 575e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera case ConversionSpecifier::aArg: 576e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera case ConversionSpecifier::AArg: 577e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera case ConversionSpecifier::fArg: 578e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera case ConversionSpecifier::FArg: 579e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera case ConversionSpecifier::eArg: 580e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera case ConversionSpecifier::EArg: 581e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera case ConversionSpecifier::gArg: 582e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera case ConversionSpecifier::GArg: 583e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera return true; 584e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera // GNU extension. 585e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera case ConversionSpecifier::dArg: 586e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera case ConversionSpecifier::iArg: 587e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera case ConversionSpecifier::oArg: 588e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera case ConversionSpecifier::uArg: 589e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera case ConversionSpecifier::xArg: 590e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera case ConversionSpecifier::XArg: 591e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera return true; 592e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera default: 593e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera return false; 594e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera } 595e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera 596e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera case LengthModifier::AsAllocate: 597e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera switch (CS.getKind()) { 598e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera case ConversionSpecifier::sArg: 599e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera case ConversionSpecifier::SArg: 600e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera case ConversionSpecifier::ScanListArg: 601e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera return true; 602e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera default: 603e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera return false; 604e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera } 605e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera 606e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera case LengthModifier::AsMAllocate: 607e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera switch (CS.getKind()) { 608e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera case ConversionSpecifier::cArg: 609e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera case ConversionSpecifier::CArg: 610e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera case ConversionSpecifier::sArg: 611e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera case ConversionSpecifier::SArg: 612e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera case ConversionSpecifier::ScanListArg: 613e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera return true; 614e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera default: 615e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera return false; 616e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera } 617e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera } 618e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera llvm_unreachable("Invalid LengthModifier Kind!"); 619e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera} 620e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera 621e229751d11692ede7fed3b56472f2d020767b412Ricardo Cerverabool FormatSpecifier::hasStandardLengthModifier() const { 622e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera switch (LM.getKind()) { 623e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera case LengthModifier::None: 624e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera case LengthModifier::AsChar: 625e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera case LengthModifier::AsShort: 626e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera case LengthModifier::AsLong: 627e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera case LengthModifier::AsLongLong: 628e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera case LengthModifier::AsIntMax: 629e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera case LengthModifier::AsSizeT: 630e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera case LengthModifier::AsPtrDiff: 631e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera case LengthModifier::AsLongDouble: 632e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera return true; 633e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera case LengthModifier::AsAllocate: 634e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera case LengthModifier::AsMAllocate: 635e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera case LengthModifier::AsQuad: 636e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera return false; 637e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera } 638e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera llvm_unreachable("Invalid LengthModifier Kind!"); 639e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera} 640e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera 641e229751d11692ede7fed3b56472f2d020767b412Ricardo Cerverabool FormatSpecifier::hasStandardConversionSpecifier(const LangOptions &LangOpt) const { 642e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera switch (CS.getKind()) { 643e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera case ConversionSpecifier::cArg: 644e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera case ConversionSpecifier::dArg: 645e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera case ConversionSpecifier::iArg: 646e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera case ConversionSpecifier::oArg: 647e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera case ConversionSpecifier::uArg: 648e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera case ConversionSpecifier::xArg: 649e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera case ConversionSpecifier::XArg: 650e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera case ConversionSpecifier::fArg: 651e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera case ConversionSpecifier::FArg: 652e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera case ConversionSpecifier::eArg: 653e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera case ConversionSpecifier::EArg: 654e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera case ConversionSpecifier::gArg: 655e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera case ConversionSpecifier::GArg: 656e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera case ConversionSpecifier::aArg: 657e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera case ConversionSpecifier::AArg: 658e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera case ConversionSpecifier::sArg: 659e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera case ConversionSpecifier::pArg: 660e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera case ConversionSpecifier::nArg: 661e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera case ConversionSpecifier::ObjCObjArg: 662e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera case ConversionSpecifier::ScanListArg: 663e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera case ConversionSpecifier::PercentArg: 664e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera return true; 665e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera case ConversionSpecifier::CArg: 666e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera case ConversionSpecifier::SArg: 667e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera return LangOpt.ObjC1 || LangOpt.ObjC2; 668e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera case ConversionSpecifier::InvalidSpecifier: 669e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera case ConversionSpecifier::PrintErrno: 670e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera return false; 671e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera } 672e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera llvm_unreachable("Invalid ConversionSpecifier Kind!"); 673e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera} 674e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera 675e229751d11692ede7fed3b56472f2d020767b412Ricardo Cerverabool FormatSpecifier::hasStandardLengthConversionCombination() const { 676e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera if (LM.getKind() == LengthModifier::AsLongDouble) { 677e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera switch(CS.getKind()) { 678e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera case ConversionSpecifier::dArg: 679e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera case ConversionSpecifier::iArg: 680e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera case ConversionSpecifier::oArg: 681e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera case ConversionSpecifier::uArg: 682e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera case ConversionSpecifier::xArg: 683e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera case ConversionSpecifier::XArg: 684e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera return false; 685e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera default: 686e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera return true; 687e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera } 688e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera } 689e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera return true; 690e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera} 691e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera 692e229751d11692ede7fed3b56472f2d020767b412Ricardo Cerverabool FormatSpecifier::namedTypeToLengthModifier(QualType QT, 693e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera LengthModifier &LM) { 694e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera assert(isa<TypedefType>(QT) && "Expected a TypedefType"); 695e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera const TypedefNameDecl *Typedef = cast<TypedefType>(QT)->getDecl(); 696e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera 697e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera for (;;) { 698e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera const IdentifierInfo *Identifier = Typedef->getIdentifier(); 699e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera if (Identifier->getName() == "size_t") { 700e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera LM.setKind(LengthModifier::AsSizeT); 701e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera return true; 702e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera } else if (Identifier->getName() == "ssize_t") { 703e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera // Not C99, but common in Unix. 704e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera LM.setKind(LengthModifier::AsSizeT); 705e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera return true; 706e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera } else if (Identifier->getName() == "intmax_t") { 707e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera LM.setKind(LengthModifier::AsIntMax); 708e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera return true; 709e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera } else if (Identifier->getName() == "uintmax_t") { 710e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera LM.setKind(LengthModifier::AsIntMax); 711e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera return true; 712e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera } else if (Identifier->getName() == "ptrdiff_t") { 713e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera LM.setKind(LengthModifier::AsPtrDiff); 714e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera return true; 715e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera } 716e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera 717e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera QualType T = Typedef->getUnderlyingType(); 718e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera if (!isa<TypedefType>(T)) 719e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera break; 720e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera 721e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera Typedef = cast<TypedefType>(T)->getDecl(); 722e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera } 723e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera return false; 724e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera} 725e229751d11692ede7fed3b56472f2d020767b412Ricardo Cervera