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