1*67e74705SXin Li // FormatString.cpp - Common stuff for handling printf/scanf formats -*- C++ -*-
2*67e74705SXin Li //
3*67e74705SXin Li // The LLVM Compiler Infrastructure
4*67e74705SXin Li //
5*67e74705SXin Li // This file is distributed under the University of Illinois Open Source
6*67e74705SXin Li // License. See LICENSE.TXT for details.
7*67e74705SXin Li //
8*67e74705SXin Li //===----------------------------------------------------------------------===//
9*67e74705SXin Li //
10*67e74705SXin Li // Shared details for processing format strings of printf and scanf
11*67e74705SXin Li // (and friends).
12*67e74705SXin Li //
13*67e74705SXin Li //===----------------------------------------------------------------------===//
14*67e74705SXin Li
15*67e74705SXin Li #include "FormatStringParsing.h"
16*67e74705SXin Li #include "clang/Basic/LangOptions.h"
17*67e74705SXin Li #include "clang/Basic/TargetInfo.h"
18*67e74705SXin Li #include "llvm/Support/ConvertUTF.h"
19*67e74705SXin Li
20*67e74705SXin Li using clang::analyze_format_string::ArgType;
21*67e74705SXin Li using clang::analyze_format_string::FormatStringHandler;
22*67e74705SXin Li using clang::analyze_format_string::FormatSpecifier;
23*67e74705SXin Li using clang::analyze_format_string::LengthModifier;
24*67e74705SXin Li using clang::analyze_format_string::OptionalAmount;
25*67e74705SXin Li using clang::analyze_format_string::PositionContext;
26*67e74705SXin Li using clang::analyze_format_string::ConversionSpecifier;
27*67e74705SXin Li using namespace clang;
28*67e74705SXin Li
29*67e74705SXin Li // Key function to FormatStringHandler.
~FormatStringHandler()30*67e74705SXin Li FormatStringHandler::~FormatStringHandler() {}
31*67e74705SXin Li
32*67e74705SXin Li //===----------------------------------------------------------------------===//
33*67e74705SXin Li // Functions for parsing format strings components in both printf and
34*67e74705SXin Li // scanf format strings.
35*67e74705SXin Li //===----------------------------------------------------------------------===//
36*67e74705SXin Li
37*67e74705SXin Li OptionalAmount
ParseAmount(const char * & Beg,const char * E)38*67e74705SXin Li clang::analyze_format_string::ParseAmount(const char *&Beg, const char *E) {
39*67e74705SXin Li const char *I = Beg;
40*67e74705SXin Li UpdateOnReturn <const char*> UpdateBeg(Beg, I);
41*67e74705SXin Li
42*67e74705SXin Li unsigned accumulator = 0;
43*67e74705SXin Li bool hasDigits = false;
44*67e74705SXin Li
45*67e74705SXin Li for ( ; I != E; ++I) {
46*67e74705SXin Li char c = *I;
47*67e74705SXin Li if (c >= '0' && c <= '9') {
48*67e74705SXin Li hasDigits = true;
49*67e74705SXin Li accumulator = (accumulator * 10) + (c - '0');
50*67e74705SXin Li continue;
51*67e74705SXin Li }
52*67e74705SXin Li
53*67e74705SXin Li if (hasDigits)
54*67e74705SXin Li return OptionalAmount(OptionalAmount::Constant, accumulator, Beg, I - Beg,
55*67e74705SXin Li false);
56*67e74705SXin Li
57*67e74705SXin Li break;
58*67e74705SXin Li }
59*67e74705SXin Li
60*67e74705SXin Li return OptionalAmount();
61*67e74705SXin Li }
62*67e74705SXin Li
63*67e74705SXin Li OptionalAmount
ParseNonPositionAmount(const char * & Beg,const char * E,unsigned & argIndex)64*67e74705SXin Li clang::analyze_format_string::ParseNonPositionAmount(const char *&Beg,
65*67e74705SXin Li const char *E,
66*67e74705SXin Li unsigned &argIndex) {
67*67e74705SXin Li if (*Beg == '*') {
68*67e74705SXin Li ++Beg;
69*67e74705SXin Li return OptionalAmount(OptionalAmount::Arg, argIndex++, Beg, 0, false);
70*67e74705SXin Li }
71*67e74705SXin Li
72*67e74705SXin Li return ParseAmount(Beg, E);
73*67e74705SXin Li }
74*67e74705SXin Li
75*67e74705SXin Li OptionalAmount
ParsePositionAmount(FormatStringHandler & H,const char * Start,const char * & Beg,const char * E,PositionContext p)76*67e74705SXin Li clang::analyze_format_string::ParsePositionAmount(FormatStringHandler &H,
77*67e74705SXin Li const char *Start,
78*67e74705SXin Li const char *&Beg,
79*67e74705SXin Li const char *E,
80*67e74705SXin Li PositionContext p) {
81*67e74705SXin Li if (*Beg == '*') {
82*67e74705SXin Li const char *I = Beg + 1;
83*67e74705SXin Li const OptionalAmount &Amt = ParseAmount(I, E);
84*67e74705SXin Li
85*67e74705SXin Li if (Amt.getHowSpecified() == OptionalAmount::NotSpecified) {
86*67e74705SXin Li H.HandleInvalidPosition(Beg, I - Beg, p);
87*67e74705SXin Li return OptionalAmount(false);
88*67e74705SXin Li }
89*67e74705SXin Li
90*67e74705SXin Li if (I == E) {
91*67e74705SXin Li // No more characters left?
92*67e74705SXin Li H.HandleIncompleteSpecifier(Start, E - Start);
93*67e74705SXin Li return OptionalAmount(false);
94*67e74705SXin Li }
95*67e74705SXin Li
96*67e74705SXin Li assert(Amt.getHowSpecified() == OptionalAmount::Constant);
97*67e74705SXin Li
98*67e74705SXin Li if (*I == '$') {
99*67e74705SXin Li // Handle positional arguments
100*67e74705SXin Li
101*67e74705SXin Li // Special case: '*0$', since this is an easy mistake.
102*67e74705SXin Li if (Amt.getConstantAmount() == 0) {
103*67e74705SXin Li H.HandleZeroPosition(Beg, I - Beg + 1);
104*67e74705SXin Li return OptionalAmount(false);
105*67e74705SXin Li }
106*67e74705SXin Li
107*67e74705SXin Li const char *Tmp = Beg;
108*67e74705SXin Li Beg = ++I;
109*67e74705SXin Li
110*67e74705SXin Li return OptionalAmount(OptionalAmount::Arg, Amt.getConstantAmount() - 1,
111*67e74705SXin Li Tmp, 0, true);
112*67e74705SXin Li }
113*67e74705SXin Li
114*67e74705SXin Li H.HandleInvalidPosition(Beg, I - Beg, p);
115*67e74705SXin Li return OptionalAmount(false);
116*67e74705SXin Li }
117*67e74705SXin Li
118*67e74705SXin Li return ParseAmount(Beg, E);
119*67e74705SXin Li }
120*67e74705SXin Li
121*67e74705SXin Li
122*67e74705SXin Li bool
ParseFieldWidth(FormatStringHandler & H,FormatSpecifier & CS,const char * Start,const char * & Beg,const char * E,unsigned * argIndex)123*67e74705SXin Li clang::analyze_format_string::ParseFieldWidth(FormatStringHandler &H,
124*67e74705SXin Li FormatSpecifier &CS,
125*67e74705SXin Li const char *Start,
126*67e74705SXin Li const char *&Beg, const char *E,
127*67e74705SXin Li unsigned *argIndex) {
128*67e74705SXin Li // FIXME: Support negative field widths.
129*67e74705SXin Li if (argIndex) {
130*67e74705SXin Li CS.setFieldWidth(ParseNonPositionAmount(Beg, E, *argIndex));
131*67e74705SXin Li }
132*67e74705SXin Li else {
133*67e74705SXin Li const OptionalAmount Amt =
134*67e74705SXin Li ParsePositionAmount(H, Start, Beg, E,
135*67e74705SXin Li analyze_format_string::FieldWidthPos);
136*67e74705SXin Li
137*67e74705SXin Li if (Amt.isInvalid())
138*67e74705SXin Li return true;
139*67e74705SXin Li CS.setFieldWidth(Amt);
140*67e74705SXin Li }
141*67e74705SXin Li return false;
142*67e74705SXin Li }
143*67e74705SXin Li
144*67e74705SXin Li bool
ParseArgPosition(FormatStringHandler & H,FormatSpecifier & FS,const char * Start,const char * & Beg,const char * E)145*67e74705SXin Li clang::analyze_format_string::ParseArgPosition(FormatStringHandler &H,
146*67e74705SXin Li FormatSpecifier &FS,
147*67e74705SXin Li const char *Start,
148*67e74705SXin Li const char *&Beg,
149*67e74705SXin Li const char *E) {
150*67e74705SXin Li const char *I = Beg;
151*67e74705SXin Li
152*67e74705SXin Li const OptionalAmount &Amt = ParseAmount(I, E);
153*67e74705SXin Li
154*67e74705SXin Li if (I == E) {
155*67e74705SXin Li // No more characters left?
156*67e74705SXin Li H.HandleIncompleteSpecifier(Start, E - Start);
157*67e74705SXin Li return true;
158*67e74705SXin Li }
159*67e74705SXin Li
160*67e74705SXin Li if (Amt.getHowSpecified() == OptionalAmount::Constant && *(I++) == '$') {
161*67e74705SXin Li // Warn that positional arguments are non-standard.
162*67e74705SXin Li H.HandlePosition(Start, I - Start);
163*67e74705SXin Li
164*67e74705SXin Li // Special case: '%0$', since this is an easy mistake.
165*67e74705SXin Li if (Amt.getConstantAmount() == 0) {
166*67e74705SXin Li H.HandleZeroPosition(Start, I - Start);
167*67e74705SXin Li return true;
168*67e74705SXin Li }
169*67e74705SXin Li
170*67e74705SXin Li FS.setArgIndex(Amt.getConstantAmount() - 1);
171*67e74705SXin Li FS.setUsesPositionalArg();
172*67e74705SXin Li // Update the caller's pointer if we decided to consume
173*67e74705SXin Li // these characters.
174*67e74705SXin Li Beg = I;
175*67e74705SXin Li return false;
176*67e74705SXin Li }
177*67e74705SXin Li
178*67e74705SXin Li return false;
179*67e74705SXin Li }
180*67e74705SXin Li
181*67e74705SXin Li bool
ParseLengthModifier(FormatSpecifier & FS,const char * & I,const char * E,const LangOptions & LO,bool IsScanf)182*67e74705SXin Li clang::analyze_format_string::ParseLengthModifier(FormatSpecifier &FS,
183*67e74705SXin Li const char *&I,
184*67e74705SXin Li const char *E,
185*67e74705SXin Li const LangOptions &LO,
186*67e74705SXin Li bool IsScanf) {
187*67e74705SXin Li LengthModifier::Kind lmKind = LengthModifier::None;
188*67e74705SXin Li const char *lmPosition = I;
189*67e74705SXin Li switch (*I) {
190*67e74705SXin Li default:
191*67e74705SXin Li return false;
192*67e74705SXin Li case 'h':
193*67e74705SXin Li ++I;
194*67e74705SXin Li if (I != E && *I == 'h') {
195*67e74705SXin Li ++I;
196*67e74705SXin Li lmKind = LengthModifier::AsChar;
197*67e74705SXin Li } else {
198*67e74705SXin Li lmKind = LengthModifier::AsShort;
199*67e74705SXin Li }
200*67e74705SXin Li break;
201*67e74705SXin Li case 'l':
202*67e74705SXin Li ++I;
203*67e74705SXin Li if (I != E && *I == 'l') {
204*67e74705SXin Li ++I;
205*67e74705SXin Li lmKind = LengthModifier::AsLongLong;
206*67e74705SXin Li } else {
207*67e74705SXin Li lmKind = LengthModifier::AsLong;
208*67e74705SXin Li }
209*67e74705SXin Li break;
210*67e74705SXin Li case 'j': lmKind = LengthModifier::AsIntMax; ++I; break;
211*67e74705SXin Li case 'z': lmKind = LengthModifier::AsSizeT; ++I; break;
212*67e74705SXin Li case 't': lmKind = LengthModifier::AsPtrDiff; ++I; break;
213*67e74705SXin Li case 'L': lmKind = LengthModifier::AsLongDouble; ++I; break;
214*67e74705SXin Li case 'q': lmKind = LengthModifier::AsQuad; ++I; break;
215*67e74705SXin Li case 'a':
216*67e74705SXin Li if (IsScanf && !LO.C99 && !LO.CPlusPlus11) {
217*67e74705SXin Li // For scanf in C90, look at the next character to see if this should
218*67e74705SXin Li // be parsed as the GNU extension 'a' length modifier. If not, this
219*67e74705SXin Li // will be parsed as a conversion specifier.
220*67e74705SXin Li ++I;
221*67e74705SXin Li if (I != E && (*I == 's' || *I == 'S' || *I == '[')) {
222*67e74705SXin Li lmKind = LengthModifier::AsAllocate;
223*67e74705SXin Li break;
224*67e74705SXin Li }
225*67e74705SXin Li --I;
226*67e74705SXin Li }
227*67e74705SXin Li return false;
228*67e74705SXin Li case 'm':
229*67e74705SXin Li if (IsScanf) {
230*67e74705SXin Li lmKind = LengthModifier::AsMAllocate;
231*67e74705SXin Li ++I;
232*67e74705SXin Li break;
233*67e74705SXin Li }
234*67e74705SXin Li return false;
235*67e74705SXin Li // printf: AsInt64, AsInt32, AsInt3264
236*67e74705SXin Li // scanf: AsInt64
237*67e74705SXin Li case 'I':
238*67e74705SXin Li if (I + 1 != E && I + 2 != E) {
239*67e74705SXin Li if (I[1] == '6' && I[2] == '4') {
240*67e74705SXin Li I += 3;
241*67e74705SXin Li lmKind = LengthModifier::AsInt64;
242*67e74705SXin Li break;
243*67e74705SXin Li }
244*67e74705SXin Li if (IsScanf)
245*67e74705SXin Li return false;
246*67e74705SXin Li
247*67e74705SXin Li if (I[1] == '3' && I[2] == '2') {
248*67e74705SXin Li I += 3;
249*67e74705SXin Li lmKind = LengthModifier::AsInt32;
250*67e74705SXin Li break;
251*67e74705SXin Li }
252*67e74705SXin Li }
253*67e74705SXin Li ++I;
254*67e74705SXin Li lmKind = LengthModifier::AsInt3264;
255*67e74705SXin Li break;
256*67e74705SXin Li case 'w':
257*67e74705SXin Li lmKind = LengthModifier::AsWide; ++I; break;
258*67e74705SXin Li }
259*67e74705SXin Li LengthModifier lm(lmPosition, lmKind);
260*67e74705SXin Li FS.setLengthModifier(lm);
261*67e74705SXin Li return true;
262*67e74705SXin Li }
263*67e74705SXin Li
ParseUTF8InvalidSpecifier(const char * SpecifierBegin,const char * FmtStrEnd,unsigned & Len)264*67e74705SXin Li bool clang::analyze_format_string::ParseUTF8InvalidSpecifier(
265*67e74705SXin Li const char *SpecifierBegin, const char *FmtStrEnd, unsigned &Len) {
266*67e74705SXin Li if (SpecifierBegin + 1 >= FmtStrEnd)
267*67e74705SXin Li return false;
268*67e74705SXin Li
269*67e74705SXin Li const UTF8 *SB = reinterpret_cast<const UTF8 *>(SpecifierBegin + 1);
270*67e74705SXin Li const UTF8 *SE = reinterpret_cast<const UTF8 *>(FmtStrEnd);
271*67e74705SXin Li const char FirstByte = *SB;
272*67e74705SXin Li
273*67e74705SXin Li // If the invalid specifier is a multibyte UTF-8 string, return the
274*67e74705SXin Li // total length accordingly so that the conversion specifier can be
275*67e74705SXin Li // properly updated to reflect a complete UTF-8 specifier.
276*67e74705SXin Li unsigned NumBytes = getNumBytesForUTF8(FirstByte);
277*67e74705SXin Li if (NumBytes == 1)
278*67e74705SXin Li return false;
279*67e74705SXin Li if (SB + NumBytes > SE)
280*67e74705SXin Li return false;
281*67e74705SXin Li
282*67e74705SXin Li Len = NumBytes + 1;
283*67e74705SXin Li return true;
284*67e74705SXin Li }
285*67e74705SXin Li
286*67e74705SXin Li //===----------------------------------------------------------------------===//
287*67e74705SXin Li // Methods on ArgType.
288*67e74705SXin Li //===----------------------------------------------------------------------===//
289*67e74705SXin Li
290*67e74705SXin Li clang::analyze_format_string::ArgType::MatchKind
matchesType(ASTContext & C,QualType argTy) const291*67e74705SXin Li ArgType::matchesType(ASTContext &C, QualType argTy) const {
292*67e74705SXin Li if (Ptr) {
293*67e74705SXin Li // It has to be a pointer.
294*67e74705SXin Li const PointerType *PT = argTy->getAs<PointerType>();
295*67e74705SXin Li if (!PT)
296*67e74705SXin Li return NoMatch;
297*67e74705SXin Li
298*67e74705SXin Li // We cannot write through a const qualified pointer.
299*67e74705SXin Li if (PT->getPointeeType().isConstQualified())
300*67e74705SXin Li return NoMatch;
301*67e74705SXin Li
302*67e74705SXin Li argTy = PT->getPointeeType();
303*67e74705SXin Li }
304*67e74705SXin Li
305*67e74705SXin Li switch (K) {
306*67e74705SXin Li case InvalidTy:
307*67e74705SXin Li llvm_unreachable("ArgType must be valid");
308*67e74705SXin Li
309*67e74705SXin Li case UnknownTy:
310*67e74705SXin Li return Match;
311*67e74705SXin Li
312*67e74705SXin Li case AnyCharTy: {
313*67e74705SXin Li if (const EnumType *ETy = argTy->getAs<EnumType>())
314*67e74705SXin Li argTy = ETy->getDecl()->getIntegerType();
315*67e74705SXin Li
316*67e74705SXin Li if (const BuiltinType *BT = argTy->getAs<BuiltinType>())
317*67e74705SXin Li switch (BT->getKind()) {
318*67e74705SXin Li default:
319*67e74705SXin Li break;
320*67e74705SXin Li case BuiltinType::Char_S:
321*67e74705SXin Li case BuiltinType::SChar:
322*67e74705SXin Li case BuiltinType::UChar:
323*67e74705SXin Li case BuiltinType::Char_U:
324*67e74705SXin Li return Match;
325*67e74705SXin Li }
326*67e74705SXin Li return NoMatch;
327*67e74705SXin Li }
328*67e74705SXin Li
329*67e74705SXin Li case SpecificTy: {
330*67e74705SXin Li if (const EnumType *ETy = argTy->getAs<EnumType>())
331*67e74705SXin Li argTy = ETy->getDecl()->getIntegerType();
332*67e74705SXin Li argTy = C.getCanonicalType(argTy).getUnqualifiedType();
333*67e74705SXin Li
334*67e74705SXin Li if (T == argTy)
335*67e74705SXin Li return Match;
336*67e74705SXin Li // Check for "compatible types".
337*67e74705SXin Li if (const BuiltinType *BT = argTy->getAs<BuiltinType>())
338*67e74705SXin Li switch (BT->getKind()) {
339*67e74705SXin Li default:
340*67e74705SXin Li break;
341*67e74705SXin Li case BuiltinType::Char_S:
342*67e74705SXin Li case BuiltinType::SChar:
343*67e74705SXin Li case BuiltinType::Char_U:
344*67e74705SXin Li case BuiltinType::UChar:
345*67e74705SXin Li return T == C.UnsignedCharTy || T == C.SignedCharTy ? Match
346*67e74705SXin Li : NoMatch;
347*67e74705SXin Li case BuiltinType::Short:
348*67e74705SXin Li return T == C.UnsignedShortTy ? Match : NoMatch;
349*67e74705SXin Li case BuiltinType::UShort:
350*67e74705SXin Li return T == C.ShortTy ? Match : NoMatch;
351*67e74705SXin Li case BuiltinType::Int:
352*67e74705SXin Li return T == C.UnsignedIntTy ? Match : NoMatch;
353*67e74705SXin Li case BuiltinType::UInt:
354*67e74705SXin Li return T == C.IntTy ? Match : NoMatch;
355*67e74705SXin Li case BuiltinType::Long:
356*67e74705SXin Li return T == C.UnsignedLongTy ? Match : NoMatch;
357*67e74705SXin Li case BuiltinType::ULong:
358*67e74705SXin Li return T == C.LongTy ? Match : NoMatch;
359*67e74705SXin Li case BuiltinType::LongLong:
360*67e74705SXin Li return T == C.UnsignedLongLongTy ? Match : NoMatch;
361*67e74705SXin Li case BuiltinType::ULongLong:
362*67e74705SXin Li return T == C.LongLongTy ? Match : NoMatch;
363*67e74705SXin Li }
364*67e74705SXin Li return NoMatch;
365*67e74705SXin Li }
366*67e74705SXin Li
367*67e74705SXin Li case CStrTy: {
368*67e74705SXin Li const PointerType *PT = argTy->getAs<PointerType>();
369*67e74705SXin Li if (!PT)
370*67e74705SXin Li return NoMatch;
371*67e74705SXin Li QualType pointeeTy = PT->getPointeeType();
372*67e74705SXin Li if (const BuiltinType *BT = pointeeTy->getAs<BuiltinType>())
373*67e74705SXin Li switch (BT->getKind()) {
374*67e74705SXin Li case BuiltinType::Void:
375*67e74705SXin Li case BuiltinType::Char_U:
376*67e74705SXin Li case BuiltinType::UChar:
377*67e74705SXin Li case BuiltinType::Char_S:
378*67e74705SXin Li case BuiltinType::SChar:
379*67e74705SXin Li return Match;
380*67e74705SXin Li default:
381*67e74705SXin Li break;
382*67e74705SXin Li }
383*67e74705SXin Li
384*67e74705SXin Li return NoMatch;
385*67e74705SXin Li }
386*67e74705SXin Li
387*67e74705SXin Li case WCStrTy: {
388*67e74705SXin Li const PointerType *PT = argTy->getAs<PointerType>();
389*67e74705SXin Li if (!PT)
390*67e74705SXin Li return NoMatch;
391*67e74705SXin Li QualType pointeeTy =
392*67e74705SXin Li C.getCanonicalType(PT->getPointeeType()).getUnqualifiedType();
393*67e74705SXin Li return pointeeTy == C.getWideCharType() ? Match : NoMatch;
394*67e74705SXin Li }
395*67e74705SXin Li
396*67e74705SXin Li case WIntTy: {
397*67e74705SXin Li
398*67e74705SXin Li QualType PromoArg =
399*67e74705SXin Li argTy->isPromotableIntegerType()
400*67e74705SXin Li ? C.getPromotedIntegerType(argTy) : argTy;
401*67e74705SXin Li
402*67e74705SXin Li QualType WInt = C.getCanonicalType(C.getWIntType()).getUnqualifiedType();
403*67e74705SXin Li PromoArg = C.getCanonicalType(PromoArg).getUnqualifiedType();
404*67e74705SXin Li
405*67e74705SXin Li // If the promoted argument is the corresponding signed type of the
406*67e74705SXin Li // wint_t type, then it should match.
407*67e74705SXin Li if (PromoArg->hasSignedIntegerRepresentation() &&
408*67e74705SXin Li C.getCorrespondingUnsignedType(PromoArg) == WInt)
409*67e74705SXin Li return Match;
410*67e74705SXin Li
411*67e74705SXin Li return WInt == PromoArg ? Match : NoMatch;
412*67e74705SXin Li }
413*67e74705SXin Li
414*67e74705SXin Li case CPointerTy:
415*67e74705SXin Li if (argTy->isVoidPointerType()) {
416*67e74705SXin Li return Match;
417*67e74705SXin Li } if (argTy->isPointerType() || argTy->isObjCObjectPointerType() ||
418*67e74705SXin Li argTy->isBlockPointerType() || argTy->isNullPtrType()) {
419*67e74705SXin Li return NoMatchPedantic;
420*67e74705SXin Li } else {
421*67e74705SXin Li return NoMatch;
422*67e74705SXin Li }
423*67e74705SXin Li
424*67e74705SXin Li case ObjCPointerTy: {
425*67e74705SXin Li if (argTy->getAs<ObjCObjectPointerType>() ||
426*67e74705SXin Li argTy->getAs<BlockPointerType>())
427*67e74705SXin Li return Match;
428*67e74705SXin Li
429*67e74705SXin Li // Handle implicit toll-free bridging.
430*67e74705SXin Li if (const PointerType *PT = argTy->getAs<PointerType>()) {
431*67e74705SXin Li // Things such as CFTypeRef are really just opaque pointers
432*67e74705SXin Li // to C structs representing CF types that can often be bridged
433*67e74705SXin Li // to Objective-C objects. Since the compiler doesn't know which
434*67e74705SXin Li // structs can be toll-free bridged, we just accept them all.
435*67e74705SXin Li QualType pointee = PT->getPointeeType();
436*67e74705SXin Li if (pointee->getAsStructureType() || pointee->isVoidType())
437*67e74705SXin Li return Match;
438*67e74705SXin Li }
439*67e74705SXin Li return NoMatch;
440*67e74705SXin Li }
441*67e74705SXin Li }
442*67e74705SXin Li
443*67e74705SXin Li llvm_unreachable("Invalid ArgType Kind!");
444*67e74705SXin Li }
445*67e74705SXin Li
getRepresentativeType(ASTContext & C) const446*67e74705SXin Li QualType ArgType::getRepresentativeType(ASTContext &C) const {
447*67e74705SXin Li QualType Res;
448*67e74705SXin Li switch (K) {
449*67e74705SXin Li case InvalidTy:
450*67e74705SXin Li llvm_unreachable("No representative type for Invalid ArgType");
451*67e74705SXin Li case UnknownTy:
452*67e74705SXin Li llvm_unreachable("No representative type for Unknown ArgType");
453*67e74705SXin Li case AnyCharTy:
454*67e74705SXin Li Res = C.CharTy;
455*67e74705SXin Li break;
456*67e74705SXin Li case SpecificTy:
457*67e74705SXin Li Res = T;
458*67e74705SXin Li break;
459*67e74705SXin Li case CStrTy:
460*67e74705SXin Li Res = C.getPointerType(C.CharTy);
461*67e74705SXin Li break;
462*67e74705SXin Li case WCStrTy:
463*67e74705SXin Li Res = C.getPointerType(C.getWideCharType());
464*67e74705SXin Li break;
465*67e74705SXin Li case ObjCPointerTy:
466*67e74705SXin Li Res = C.ObjCBuiltinIdTy;
467*67e74705SXin Li break;
468*67e74705SXin Li case CPointerTy:
469*67e74705SXin Li Res = C.VoidPtrTy;
470*67e74705SXin Li break;
471*67e74705SXin Li case WIntTy: {
472*67e74705SXin Li Res = C.getWIntType();
473*67e74705SXin Li break;
474*67e74705SXin Li }
475*67e74705SXin Li }
476*67e74705SXin Li
477*67e74705SXin Li if (Ptr)
478*67e74705SXin Li Res = C.getPointerType(Res);
479*67e74705SXin Li return Res;
480*67e74705SXin Li }
481*67e74705SXin Li
getRepresentativeTypeName(ASTContext & C) const482*67e74705SXin Li std::string ArgType::getRepresentativeTypeName(ASTContext &C) const {
483*67e74705SXin Li std::string S = getRepresentativeType(C).getAsString();
484*67e74705SXin Li
485*67e74705SXin Li std::string Alias;
486*67e74705SXin Li if (Name) {
487*67e74705SXin Li // Use a specific name for this type, e.g. "size_t".
488*67e74705SXin Li Alias = Name;
489*67e74705SXin Li if (Ptr) {
490*67e74705SXin Li // If ArgType is actually a pointer to T, append an asterisk.
491*67e74705SXin Li Alias += (Alias[Alias.size()-1] == '*') ? "*" : " *";
492*67e74705SXin Li }
493*67e74705SXin Li // If Alias is the same as the underlying type, e.g. wchar_t, then drop it.
494*67e74705SXin Li if (S == Alias)
495*67e74705SXin Li Alias.clear();
496*67e74705SXin Li }
497*67e74705SXin Li
498*67e74705SXin Li if (!Alias.empty())
499*67e74705SXin Li return std::string("'") + Alias + "' (aka '" + S + "')";
500*67e74705SXin Li return std::string("'") + S + "'";
501*67e74705SXin Li }
502*67e74705SXin Li
503*67e74705SXin Li
504*67e74705SXin Li //===----------------------------------------------------------------------===//
505*67e74705SXin Li // Methods on OptionalAmount.
506*67e74705SXin Li //===----------------------------------------------------------------------===//
507*67e74705SXin Li
508*67e74705SXin Li ArgType
getArgType(ASTContext & Ctx) const509*67e74705SXin Li analyze_format_string::OptionalAmount::getArgType(ASTContext &Ctx) const {
510*67e74705SXin Li return Ctx.IntTy;
511*67e74705SXin Li }
512*67e74705SXin Li
513*67e74705SXin Li //===----------------------------------------------------------------------===//
514*67e74705SXin Li // Methods on LengthModifier.
515*67e74705SXin Li //===----------------------------------------------------------------------===//
516*67e74705SXin Li
517*67e74705SXin Li const char *
toString() const518*67e74705SXin Li analyze_format_string::LengthModifier::toString() const {
519*67e74705SXin Li switch (kind) {
520*67e74705SXin Li case AsChar:
521*67e74705SXin Li return "hh";
522*67e74705SXin Li case AsShort:
523*67e74705SXin Li return "h";
524*67e74705SXin Li case AsLong: // or AsWideChar
525*67e74705SXin Li return "l";
526*67e74705SXin Li case AsLongLong:
527*67e74705SXin Li return "ll";
528*67e74705SXin Li case AsQuad:
529*67e74705SXin Li return "q";
530*67e74705SXin Li case AsIntMax:
531*67e74705SXin Li return "j";
532*67e74705SXin Li case AsSizeT:
533*67e74705SXin Li return "z";
534*67e74705SXin Li case AsPtrDiff:
535*67e74705SXin Li return "t";
536*67e74705SXin Li case AsInt32:
537*67e74705SXin Li return "I32";
538*67e74705SXin Li case AsInt3264:
539*67e74705SXin Li return "I";
540*67e74705SXin Li case AsInt64:
541*67e74705SXin Li return "I64";
542*67e74705SXin Li case AsLongDouble:
543*67e74705SXin Li return "L";
544*67e74705SXin Li case AsAllocate:
545*67e74705SXin Li return "a";
546*67e74705SXin Li case AsMAllocate:
547*67e74705SXin Li return "m";
548*67e74705SXin Li case AsWide:
549*67e74705SXin Li return "w";
550*67e74705SXin Li case None:
551*67e74705SXin Li return "";
552*67e74705SXin Li }
553*67e74705SXin Li return nullptr;
554*67e74705SXin Li }
555*67e74705SXin Li
556*67e74705SXin Li //===----------------------------------------------------------------------===//
557*67e74705SXin Li // Methods on ConversionSpecifier.
558*67e74705SXin Li //===----------------------------------------------------------------------===//
559*67e74705SXin Li
toString() const560*67e74705SXin Li const char *ConversionSpecifier::toString() const {
561*67e74705SXin Li switch (kind) {
562*67e74705SXin Li case dArg: return "d";
563*67e74705SXin Li case DArg: return "D";
564*67e74705SXin Li case iArg: return "i";
565*67e74705SXin Li case oArg: return "o";
566*67e74705SXin Li case OArg: return "O";
567*67e74705SXin Li case uArg: return "u";
568*67e74705SXin Li case UArg: return "U";
569*67e74705SXin Li case xArg: return "x";
570*67e74705SXin Li case XArg: return "X";
571*67e74705SXin Li case fArg: return "f";
572*67e74705SXin Li case FArg: return "F";
573*67e74705SXin Li case eArg: return "e";
574*67e74705SXin Li case EArg: return "E";
575*67e74705SXin Li case gArg: return "g";
576*67e74705SXin Li case GArg: return "G";
577*67e74705SXin Li case aArg: return "a";
578*67e74705SXin Li case AArg: return "A";
579*67e74705SXin Li case cArg: return "c";
580*67e74705SXin Li case sArg: return "s";
581*67e74705SXin Li case pArg: return "p";
582*67e74705SXin Li case nArg: return "n";
583*67e74705SXin Li case PercentArg: return "%";
584*67e74705SXin Li case ScanListArg: return "[";
585*67e74705SXin Li case InvalidSpecifier: return nullptr;
586*67e74705SXin Li
587*67e74705SXin Li // POSIX unicode extensions.
588*67e74705SXin Li case CArg: return "C";
589*67e74705SXin Li case SArg: return "S";
590*67e74705SXin Li
591*67e74705SXin Li // Objective-C specific specifiers.
592*67e74705SXin Li case ObjCObjArg: return "@";
593*67e74705SXin Li
594*67e74705SXin Li // FreeBSD kernel specific specifiers.
595*67e74705SXin Li case FreeBSDbArg: return "b";
596*67e74705SXin Li case FreeBSDDArg: return "D";
597*67e74705SXin Li case FreeBSDrArg: return "r";
598*67e74705SXin Li case FreeBSDyArg: return "y";
599*67e74705SXin Li
600*67e74705SXin Li // GlibC specific specifiers.
601*67e74705SXin Li case PrintErrno: return "m";
602*67e74705SXin Li
603*67e74705SXin Li // MS specific specifiers.
604*67e74705SXin Li case ZArg: return "Z";
605*67e74705SXin Li }
606*67e74705SXin Li return nullptr;
607*67e74705SXin Li }
608*67e74705SXin Li
609*67e74705SXin Li Optional<ConversionSpecifier>
getStandardSpecifier() const610*67e74705SXin Li ConversionSpecifier::getStandardSpecifier() const {
611*67e74705SXin Li ConversionSpecifier::Kind NewKind;
612*67e74705SXin Li
613*67e74705SXin Li switch (getKind()) {
614*67e74705SXin Li default:
615*67e74705SXin Li return None;
616*67e74705SXin Li case DArg:
617*67e74705SXin Li NewKind = dArg;
618*67e74705SXin Li break;
619*67e74705SXin Li case UArg:
620*67e74705SXin Li NewKind = uArg;
621*67e74705SXin Li break;
622*67e74705SXin Li case OArg:
623*67e74705SXin Li NewKind = oArg;
624*67e74705SXin Li break;
625*67e74705SXin Li }
626*67e74705SXin Li
627*67e74705SXin Li ConversionSpecifier FixedCS(*this);
628*67e74705SXin Li FixedCS.setKind(NewKind);
629*67e74705SXin Li return FixedCS;
630*67e74705SXin Li }
631*67e74705SXin Li
632*67e74705SXin Li //===----------------------------------------------------------------------===//
633*67e74705SXin Li // Methods on OptionalAmount.
634*67e74705SXin Li //===----------------------------------------------------------------------===//
635*67e74705SXin Li
toString(raw_ostream & os) const636*67e74705SXin Li void OptionalAmount::toString(raw_ostream &os) const {
637*67e74705SXin Li switch (hs) {
638*67e74705SXin Li case Invalid:
639*67e74705SXin Li case NotSpecified:
640*67e74705SXin Li return;
641*67e74705SXin Li case Arg:
642*67e74705SXin Li if (UsesDotPrefix)
643*67e74705SXin Li os << ".";
644*67e74705SXin Li if (usesPositionalArg())
645*67e74705SXin Li os << "*" << getPositionalArgIndex() << "$";
646*67e74705SXin Li else
647*67e74705SXin Li os << "*";
648*67e74705SXin Li break;
649*67e74705SXin Li case Constant:
650*67e74705SXin Li if (UsesDotPrefix)
651*67e74705SXin Li os << ".";
652*67e74705SXin Li os << amt;
653*67e74705SXin Li break;
654*67e74705SXin Li }
655*67e74705SXin Li }
656*67e74705SXin Li
hasValidLengthModifier(const TargetInfo & Target) const657*67e74705SXin Li bool FormatSpecifier::hasValidLengthModifier(const TargetInfo &Target) const {
658*67e74705SXin Li switch (LM.getKind()) {
659*67e74705SXin Li case LengthModifier::None:
660*67e74705SXin Li return true;
661*67e74705SXin Li
662*67e74705SXin Li // Handle most integer flags
663*67e74705SXin Li case LengthModifier::AsShort:
664*67e74705SXin Li if (Target.getTriple().isOSMSVCRT()) {
665*67e74705SXin Li switch (CS.getKind()) {
666*67e74705SXin Li case ConversionSpecifier::cArg:
667*67e74705SXin Li case ConversionSpecifier::CArg:
668*67e74705SXin Li case ConversionSpecifier::sArg:
669*67e74705SXin Li case ConversionSpecifier::SArg:
670*67e74705SXin Li case ConversionSpecifier::ZArg:
671*67e74705SXin Li return true;
672*67e74705SXin Li default:
673*67e74705SXin Li break;
674*67e74705SXin Li }
675*67e74705SXin Li }
676*67e74705SXin Li // Fall through.
677*67e74705SXin Li case LengthModifier::AsChar:
678*67e74705SXin Li case LengthModifier::AsLongLong:
679*67e74705SXin Li case LengthModifier::AsQuad:
680*67e74705SXin Li case LengthModifier::AsIntMax:
681*67e74705SXin Li case LengthModifier::AsSizeT:
682*67e74705SXin Li case LengthModifier::AsPtrDiff:
683*67e74705SXin Li switch (CS.getKind()) {
684*67e74705SXin Li case ConversionSpecifier::dArg:
685*67e74705SXin Li case ConversionSpecifier::DArg:
686*67e74705SXin Li case ConversionSpecifier::iArg:
687*67e74705SXin Li case ConversionSpecifier::oArg:
688*67e74705SXin Li case ConversionSpecifier::OArg:
689*67e74705SXin Li case ConversionSpecifier::uArg:
690*67e74705SXin Li case ConversionSpecifier::UArg:
691*67e74705SXin Li case ConversionSpecifier::xArg:
692*67e74705SXin Li case ConversionSpecifier::XArg:
693*67e74705SXin Li case ConversionSpecifier::nArg:
694*67e74705SXin Li return true;
695*67e74705SXin Li case ConversionSpecifier::FreeBSDrArg:
696*67e74705SXin Li case ConversionSpecifier::FreeBSDyArg:
697*67e74705SXin Li return Target.getTriple().isOSFreeBSD() || Target.getTriple().isPS4();
698*67e74705SXin Li default:
699*67e74705SXin Li return false;
700*67e74705SXin Li }
701*67e74705SXin Li
702*67e74705SXin Li // Handle 'l' flag
703*67e74705SXin Li case LengthModifier::AsLong: // or AsWideChar
704*67e74705SXin Li switch (CS.getKind()) {
705*67e74705SXin Li case ConversionSpecifier::dArg:
706*67e74705SXin Li case ConversionSpecifier::DArg:
707*67e74705SXin Li case ConversionSpecifier::iArg:
708*67e74705SXin Li case ConversionSpecifier::oArg:
709*67e74705SXin Li case ConversionSpecifier::OArg:
710*67e74705SXin Li case ConversionSpecifier::uArg:
711*67e74705SXin Li case ConversionSpecifier::UArg:
712*67e74705SXin Li case ConversionSpecifier::xArg:
713*67e74705SXin Li case ConversionSpecifier::XArg:
714*67e74705SXin Li case ConversionSpecifier::aArg:
715*67e74705SXin Li case ConversionSpecifier::AArg:
716*67e74705SXin Li case ConversionSpecifier::fArg:
717*67e74705SXin Li case ConversionSpecifier::FArg:
718*67e74705SXin Li case ConversionSpecifier::eArg:
719*67e74705SXin Li case ConversionSpecifier::EArg:
720*67e74705SXin Li case ConversionSpecifier::gArg:
721*67e74705SXin Li case ConversionSpecifier::GArg:
722*67e74705SXin Li case ConversionSpecifier::nArg:
723*67e74705SXin Li case ConversionSpecifier::cArg:
724*67e74705SXin Li case ConversionSpecifier::sArg:
725*67e74705SXin Li case ConversionSpecifier::ScanListArg:
726*67e74705SXin Li case ConversionSpecifier::ZArg:
727*67e74705SXin Li return true;
728*67e74705SXin Li case ConversionSpecifier::FreeBSDrArg:
729*67e74705SXin Li case ConversionSpecifier::FreeBSDyArg:
730*67e74705SXin Li return Target.getTriple().isOSFreeBSD() || Target.getTriple().isPS4();
731*67e74705SXin Li default:
732*67e74705SXin Li return false;
733*67e74705SXin Li }
734*67e74705SXin Li
735*67e74705SXin Li case LengthModifier::AsLongDouble:
736*67e74705SXin Li switch (CS.getKind()) {
737*67e74705SXin Li case ConversionSpecifier::aArg:
738*67e74705SXin Li case ConversionSpecifier::AArg:
739*67e74705SXin Li case ConversionSpecifier::fArg:
740*67e74705SXin Li case ConversionSpecifier::FArg:
741*67e74705SXin Li case ConversionSpecifier::eArg:
742*67e74705SXin Li case ConversionSpecifier::EArg:
743*67e74705SXin Li case ConversionSpecifier::gArg:
744*67e74705SXin Li case ConversionSpecifier::GArg:
745*67e74705SXin Li return true;
746*67e74705SXin Li // GNU libc extension.
747*67e74705SXin Li case ConversionSpecifier::dArg:
748*67e74705SXin Li case ConversionSpecifier::iArg:
749*67e74705SXin Li case ConversionSpecifier::oArg:
750*67e74705SXin Li case ConversionSpecifier::uArg:
751*67e74705SXin Li case ConversionSpecifier::xArg:
752*67e74705SXin Li case ConversionSpecifier::XArg:
753*67e74705SXin Li return !Target.getTriple().isOSDarwin() &&
754*67e74705SXin Li !Target.getTriple().isOSWindows();
755*67e74705SXin Li default:
756*67e74705SXin Li return false;
757*67e74705SXin Li }
758*67e74705SXin Li
759*67e74705SXin Li case LengthModifier::AsAllocate:
760*67e74705SXin Li switch (CS.getKind()) {
761*67e74705SXin Li case ConversionSpecifier::sArg:
762*67e74705SXin Li case ConversionSpecifier::SArg:
763*67e74705SXin Li case ConversionSpecifier::ScanListArg:
764*67e74705SXin Li return true;
765*67e74705SXin Li default:
766*67e74705SXin Li return false;
767*67e74705SXin Li }
768*67e74705SXin Li
769*67e74705SXin Li case LengthModifier::AsMAllocate:
770*67e74705SXin Li switch (CS.getKind()) {
771*67e74705SXin Li case ConversionSpecifier::cArg:
772*67e74705SXin Li case ConversionSpecifier::CArg:
773*67e74705SXin Li case ConversionSpecifier::sArg:
774*67e74705SXin Li case ConversionSpecifier::SArg:
775*67e74705SXin Li case ConversionSpecifier::ScanListArg:
776*67e74705SXin Li return true;
777*67e74705SXin Li default:
778*67e74705SXin Li return false;
779*67e74705SXin Li }
780*67e74705SXin Li case LengthModifier::AsInt32:
781*67e74705SXin Li case LengthModifier::AsInt3264:
782*67e74705SXin Li case LengthModifier::AsInt64:
783*67e74705SXin Li switch (CS.getKind()) {
784*67e74705SXin Li case ConversionSpecifier::dArg:
785*67e74705SXin Li case ConversionSpecifier::iArg:
786*67e74705SXin Li case ConversionSpecifier::oArg:
787*67e74705SXin Li case ConversionSpecifier::uArg:
788*67e74705SXin Li case ConversionSpecifier::xArg:
789*67e74705SXin Li case ConversionSpecifier::XArg:
790*67e74705SXin Li return Target.getTriple().isOSMSVCRT();
791*67e74705SXin Li default:
792*67e74705SXin Li return false;
793*67e74705SXin Li }
794*67e74705SXin Li case LengthModifier::AsWide:
795*67e74705SXin Li switch (CS.getKind()) {
796*67e74705SXin Li case ConversionSpecifier::cArg:
797*67e74705SXin Li case ConversionSpecifier::CArg:
798*67e74705SXin Li case ConversionSpecifier::sArg:
799*67e74705SXin Li case ConversionSpecifier::SArg:
800*67e74705SXin Li case ConversionSpecifier::ZArg:
801*67e74705SXin Li return Target.getTriple().isOSMSVCRT();
802*67e74705SXin Li default:
803*67e74705SXin Li return false;
804*67e74705SXin Li }
805*67e74705SXin Li }
806*67e74705SXin Li llvm_unreachable("Invalid LengthModifier Kind!");
807*67e74705SXin Li }
808*67e74705SXin Li
hasStandardLengthModifier() const809*67e74705SXin Li bool FormatSpecifier::hasStandardLengthModifier() const {
810*67e74705SXin Li switch (LM.getKind()) {
811*67e74705SXin Li case LengthModifier::None:
812*67e74705SXin Li case LengthModifier::AsChar:
813*67e74705SXin Li case LengthModifier::AsShort:
814*67e74705SXin Li case LengthModifier::AsLong:
815*67e74705SXin Li case LengthModifier::AsLongLong:
816*67e74705SXin Li case LengthModifier::AsIntMax:
817*67e74705SXin Li case LengthModifier::AsSizeT:
818*67e74705SXin Li case LengthModifier::AsPtrDiff:
819*67e74705SXin Li case LengthModifier::AsLongDouble:
820*67e74705SXin Li return true;
821*67e74705SXin Li case LengthModifier::AsAllocate:
822*67e74705SXin Li case LengthModifier::AsMAllocate:
823*67e74705SXin Li case LengthModifier::AsQuad:
824*67e74705SXin Li case LengthModifier::AsInt32:
825*67e74705SXin Li case LengthModifier::AsInt3264:
826*67e74705SXin Li case LengthModifier::AsInt64:
827*67e74705SXin Li case LengthModifier::AsWide:
828*67e74705SXin Li return false;
829*67e74705SXin Li }
830*67e74705SXin Li llvm_unreachable("Invalid LengthModifier Kind!");
831*67e74705SXin Li }
832*67e74705SXin Li
hasStandardConversionSpecifier(const LangOptions & LangOpt) const833*67e74705SXin Li bool FormatSpecifier::hasStandardConversionSpecifier(
834*67e74705SXin Li const LangOptions &LangOpt) const {
835*67e74705SXin Li switch (CS.getKind()) {
836*67e74705SXin Li case ConversionSpecifier::cArg:
837*67e74705SXin Li case ConversionSpecifier::dArg:
838*67e74705SXin Li case ConversionSpecifier::iArg:
839*67e74705SXin Li case ConversionSpecifier::oArg:
840*67e74705SXin Li case ConversionSpecifier::uArg:
841*67e74705SXin Li case ConversionSpecifier::xArg:
842*67e74705SXin Li case ConversionSpecifier::XArg:
843*67e74705SXin Li case ConversionSpecifier::fArg:
844*67e74705SXin Li case ConversionSpecifier::FArg:
845*67e74705SXin Li case ConversionSpecifier::eArg:
846*67e74705SXin Li case ConversionSpecifier::EArg:
847*67e74705SXin Li case ConversionSpecifier::gArg:
848*67e74705SXin Li case ConversionSpecifier::GArg:
849*67e74705SXin Li case ConversionSpecifier::aArg:
850*67e74705SXin Li case ConversionSpecifier::AArg:
851*67e74705SXin Li case ConversionSpecifier::sArg:
852*67e74705SXin Li case ConversionSpecifier::pArg:
853*67e74705SXin Li case ConversionSpecifier::nArg:
854*67e74705SXin Li case ConversionSpecifier::ObjCObjArg:
855*67e74705SXin Li case ConversionSpecifier::ScanListArg:
856*67e74705SXin Li case ConversionSpecifier::PercentArg:
857*67e74705SXin Li return true;
858*67e74705SXin Li case ConversionSpecifier::CArg:
859*67e74705SXin Li case ConversionSpecifier::SArg:
860*67e74705SXin Li return LangOpt.ObjC1 || LangOpt.ObjC2;
861*67e74705SXin Li case ConversionSpecifier::InvalidSpecifier:
862*67e74705SXin Li case ConversionSpecifier::FreeBSDbArg:
863*67e74705SXin Li case ConversionSpecifier::FreeBSDDArg:
864*67e74705SXin Li case ConversionSpecifier::FreeBSDrArg:
865*67e74705SXin Li case ConversionSpecifier::FreeBSDyArg:
866*67e74705SXin Li case ConversionSpecifier::PrintErrno:
867*67e74705SXin Li case ConversionSpecifier::DArg:
868*67e74705SXin Li case ConversionSpecifier::OArg:
869*67e74705SXin Li case ConversionSpecifier::UArg:
870*67e74705SXin Li case ConversionSpecifier::ZArg:
871*67e74705SXin Li return false;
872*67e74705SXin Li }
873*67e74705SXin Li llvm_unreachable("Invalid ConversionSpecifier Kind!");
874*67e74705SXin Li }
875*67e74705SXin Li
hasStandardLengthConversionCombination() const876*67e74705SXin Li bool FormatSpecifier::hasStandardLengthConversionCombination() const {
877*67e74705SXin Li if (LM.getKind() == LengthModifier::AsLongDouble) {
878*67e74705SXin Li switch(CS.getKind()) {
879*67e74705SXin Li case ConversionSpecifier::dArg:
880*67e74705SXin Li case ConversionSpecifier::iArg:
881*67e74705SXin Li case ConversionSpecifier::oArg:
882*67e74705SXin Li case ConversionSpecifier::uArg:
883*67e74705SXin Li case ConversionSpecifier::xArg:
884*67e74705SXin Li case ConversionSpecifier::XArg:
885*67e74705SXin Li return false;
886*67e74705SXin Li default:
887*67e74705SXin Li return true;
888*67e74705SXin Li }
889*67e74705SXin Li }
890*67e74705SXin Li return true;
891*67e74705SXin Li }
892*67e74705SXin Li
getCorrectedLengthModifier() const893*67e74705SXin Li Optional<LengthModifier> FormatSpecifier::getCorrectedLengthModifier() const {
894*67e74705SXin Li if (CS.isAnyIntArg() || CS.getKind() == ConversionSpecifier::nArg) {
895*67e74705SXin Li if (LM.getKind() == LengthModifier::AsLongDouble ||
896*67e74705SXin Li LM.getKind() == LengthModifier::AsQuad) {
897*67e74705SXin Li LengthModifier FixedLM(LM);
898*67e74705SXin Li FixedLM.setKind(LengthModifier::AsLongLong);
899*67e74705SXin Li return FixedLM;
900*67e74705SXin Li }
901*67e74705SXin Li }
902*67e74705SXin Li
903*67e74705SXin Li return None;
904*67e74705SXin Li }
905*67e74705SXin Li
namedTypeToLengthModifier(QualType QT,LengthModifier & LM)906*67e74705SXin Li bool FormatSpecifier::namedTypeToLengthModifier(QualType QT,
907*67e74705SXin Li LengthModifier &LM) {
908*67e74705SXin Li assert(isa<TypedefType>(QT) && "Expected a TypedefType");
909*67e74705SXin Li const TypedefNameDecl *Typedef = cast<TypedefType>(QT)->getDecl();
910*67e74705SXin Li
911*67e74705SXin Li for (;;) {
912*67e74705SXin Li const IdentifierInfo *Identifier = Typedef->getIdentifier();
913*67e74705SXin Li if (Identifier->getName() == "size_t") {
914*67e74705SXin Li LM.setKind(LengthModifier::AsSizeT);
915*67e74705SXin Li return true;
916*67e74705SXin Li } else if (Identifier->getName() == "ssize_t") {
917*67e74705SXin Li // Not C99, but common in Unix.
918*67e74705SXin Li LM.setKind(LengthModifier::AsSizeT);
919*67e74705SXin Li return true;
920*67e74705SXin Li } else if (Identifier->getName() == "intmax_t") {
921*67e74705SXin Li LM.setKind(LengthModifier::AsIntMax);
922*67e74705SXin Li return true;
923*67e74705SXin Li } else if (Identifier->getName() == "uintmax_t") {
924*67e74705SXin Li LM.setKind(LengthModifier::AsIntMax);
925*67e74705SXin Li return true;
926*67e74705SXin Li } else if (Identifier->getName() == "ptrdiff_t") {
927*67e74705SXin Li LM.setKind(LengthModifier::AsPtrDiff);
928*67e74705SXin Li return true;
929*67e74705SXin Li }
930*67e74705SXin Li
931*67e74705SXin Li QualType T = Typedef->getUnderlyingType();
932*67e74705SXin Li if (!isa<TypedefType>(T))
933*67e74705SXin Li break;
934*67e74705SXin Li
935*67e74705SXin Li Typedef = cast<TypedefType>(T)->getDecl();
936*67e74705SXin Li }
937*67e74705SXin Li return false;
938*67e74705SXin Li }
939