]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/tools/clang/lib/AST/PrintfFormatString.cpp
MFC r345805: Unify SCSI_STATUS_BUSY retry handling with other cases.
[FreeBSD/FreeBSD.git] / contrib / llvm / tools / clang / lib / AST / PrintfFormatString.cpp
1 //== PrintfFormatString.cpp - Analysis of printf format strings --*- C++ -*-==//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // Handling of format string in printf and friends.  The structure of format
11 // strings for fprintf() are described in C99 7.19.6.1.
12 //
13 //===----------------------------------------------------------------------===//
14
15 #include "clang/AST/FormatString.h"
16 #include "clang/AST/OSLog.h"
17 #include "FormatStringParsing.h"
18 #include "clang/Basic/TargetInfo.h"
19
20 using clang::analyze_format_string::ArgType;
21 using clang::analyze_format_string::FormatStringHandler;
22 using clang::analyze_format_string::LengthModifier;
23 using clang::analyze_format_string::OptionalAmount;
24 using clang::analyze_format_string::ConversionSpecifier;
25 using clang::analyze_printf::PrintfSpecifier;
26
27 using namespace clang;
28
29 typedef clang::analyze_format_string::SpecifierResult<PrintfSpecifier>
30         PrintfSpecifierResult;
31
32 //===----------------------------------------------------------------------===//
33 // Methods for parsing format strings.
34 //===----------------------------------------------------------------------===//
35
36 using analyze_format_string::ParseNonPositionAmount;
37
38 static bool ParsePrecision(FormatStringHandler &H, PrintfSpecifier &FS,
39                            const char *Start, const char *&Beg, const char *E,
40                            unsigned *argIndex) {
41   if (argIndex) {
42     FS.setPrecision(ParseNonPositionAmount(Beg, E, *argIndex));
43   } else {
44     const OptionalAmount Amt = ParsePositionAmount(H, Start, Beg, E,
45                                            analyze_format_string::PrecisionPos);
46     if (Amt.isInvalid())
47       return true;
48     FS.setPrecision(Amt);
49   }
50   return false;
51 }
52
53 static bool ParseObjCFlags(FormatStringHandler &H, PrintfSpecifier &FS,
54                            const char *FlagBeg, const char *E, bool Warn) {
55    StringRef Flag(FlagBeg, E - FlagBeg);
56    // Currently there is only one flag.
57    if (Flag == "tt") {
58      FS.setHasObjCTechnicalTerm(FlagBeg);
59      return false;
60    }
61    // Handle either the case of no flag or an invalid flag.
62    if (Warn) {
63      if (Flag == "")
64        H.HandleEmptyObjCModifierFlag(FlagBeg, E  - FlagBeg);
65      else
66        H.HandleInvalidObjCModifierFlag(FlagBeg, E  - FlagBeg);
67    }
68    return true;
69 }
70
71 static PrintfSpecifierResult ParsePrintfSpecifier(FormatStringHandler &H,
72                                                   const char *&Beg,
73                                                   const char *E,
74                                                   unsigned &argIndex,
75                                                   const LangOptions &LO,
76                                                   const TargetInfo &Target,
77                                                   bool Warn,
78                                                   bool isFreeBSDKPrintf) {
79
80   using namespace clang::analyze_format_string;
81   using namespace clang::analyze_printf;
82
83   const char *I = Beg;
84   const char *Start = nullptr;
85   UpdateOnReturn <const char*> UpdateBeg(Beg, I);
86
87   // Look for a '%' character that indicates the start of a format specifier.
88   for ( ; I != E ; ++I) {
89     char c = *I;
90     if (c == '\0') {
91       // Detect spurious null characters, which are likely errors.
92       H.HandleNullChar(I);
93       return true;
94     }
95     if (c == '%') {
96       Start = I++;  // Record the start of the format specifier.
97       break;
98     }
99   }
100
101   // No format specifier found?
102   if (!Start)
103     return false;
104
105   if (I == E) {
106     // No more characters left?
107     if (Warn)
108       H.HandleIncompleteSpecifier(Start, E - Start);
109     return true;
110   }
111
112   PrintfSpecifier FS;
113   if (ParseArgPosition(H, FS, Start, I, E))
114     return true;
115
116   if (I == E) {
117     // No more characters left?
118     if (Warn)
119       H.HandleIncompleteSpecifier(Start, E - Start);
120     return true;
121   }
122
123   if (*I == '{') {
124     ++I;
125     unsigned char PrivacyFlags = 0;
126     StringRef MatchedStr;
127
128     do {
129       StringRef Str(I, E - I);
130       std::string Match = "^[[:space:]]*"
131                           "(private|public|sensitive|mask\\.[^[:space:],}]*)"
132                           "[[:space:]]*(,|})";
133       llvm::Regex R(Match);
134       SmallVector<StringRef, 2> Matches;
135
136       if (R.match(Str, &Matches)) {
137         MatchedStr = Matches[1];
138         I += Matches[0].size();
139
140         // Set the privacy flag if the privacy annotation in the
141         // comma-delimited segment is at least as strict as the privacy
142         // annotations in previous comma-delimited segments.
143         if (MatchedStr.startswith("mask")) {
144           StringRef MaskType = MatchedStr.substr(sizeof("mask.") - 1);
145           unsigned Size = MaskType.size();
146           if (Warn && (Size == 0 || Size > 8))
147             H.handleInvalidMaskType(MaskType);
148           FS.setMaskType(MaskType);
149         } else if (MatchedStr.equals("sensitive"))
150           PrivacyFlags = clang::analyze_os_log::OSLogBufferItem::IsSensitive;
151         else if (PrivacyFlags !=
152                  clang::analyze_os_log::OSLogBufferItem::IsSensitive &&
153                  MatchedStr.equals("private"))
154           PrivacyFlags = clang::analyze_os_log::OSLogBufferItem::IsPrivate;
155         else if (PrivacyFlags == 0 && MatchedStr.equals("public"))
156           PrivacyFlags = clang::analyze_os_log::OSLogBufferItem::IsPublic;
157       } else {
158         size_t CommaOrBracePos =
159             Str.find_if([](char c) { return c == ',' || c == '}'; });
160
161         if (CommaOrBracePos == StringRef::npos) {
162           // Neither a comma nor the closing brace was found.
163           if (Warn)
164             H.HandleIncompleteSpecifier(Start, E - Start);
165           return true;
166         }
167
168         I += CommaOrBracePos + 1;
169       }
170       // Continue until the closing brace is found.
171     } while (*(I - 1) == ',');
172
173     // Set the privacy flag.
174     switch (PrivacyFlags) {
175     case 0:
176       break;
177     case clang::analyze_os_log::OSLogBufferItem::IsPrivate:
178       FS.setIsPrivate(MatchedStr.data());
179       break;
180     case clang::analyze_os_log::OSLogBufferItem::IsPublic:
181       FS.setIsPublic(MatchedStr.data());
182       break;
183     case clang::analyze_os_log::OSLogBufferItem::IsSensitive:
184       FS.setIsSensitive(MatchedStr.data());
185       break;
186     default:
187       llvm_unreachable("Unexpected privacy flag value");
188     }
189   }
190
191   // Look for flags (if any).
192   bool hasMore = true;
193   for ( ; I != E; ++I) {
194     switch (*I) {
195       default: hasMore = false; break;
196       case '\'':
197         // FIXME: POSIX specific.  Always accept?
198         FS.setHasThousandsGrouping(I);
199         break;
200       case '-': FS.setIsLeftJustified(I); break;
201       case '+': FS.setHasPlusPrefix(I); break;
202       case ' ': FS.setHasSpacePrefix(I); break;
203       case '#': FS.setHasAlternativeForm(I); break;
204       case '0': FS.setHasLeadingZeros(I); break;
205     }
206     if (!hasMore)
207       break;
208   }
209
210   if (I == E) {
211     // No more characters left?
212     if (Warn)
213       H.HandleIncompleteSpecifier(Start, E - Start);
214     return true;
215   }
216
217   // Look for the field width (if any).
218   if (ParseFieldWidth(H, FS, Start, I, E,
219                       FS.usesPositionalArg() ? nullptr : &argIndex))
220     return true;
221
222   if (I == E) {
223     // No more characters left?
224     if (Warn)
225       H.HandleIncompleteSpecifier(Start, E - Start);
226     return true;
227   }
228
229   // Look for the precision (if any).
230   if (*I == '.') {
231     ++I;
232     if (I == E) {
233       if (Warn)
234         H.HandleIncompleteSpecifier(Start, E - Start);
235       return true;
236     }
237
238     if (ParsePrecision(H, FS, Start, I, E,
239                        FS.usesPositionalArg() ? nullptr : &argIndex))
240       return true;
241
242     if (I == E) {
243       // No more characters left?
244       if (Warn)
245         H.HandleIncompleteSpecifier(Start, E - Start);
246       return true;
247     }
248   }
249
250   if (ParseVectorModifier(H, FS, I, E, LO))
251     return true;
252
253   // Look for the length modifier.
254   if (ParseLengthModifier(FS, I, E, LO) && I == E) {
255     // No more characters left?
256     if (Warn)
257       H.HandleIncompleteSpecifier(Start, E - Start);
258     return true;
259   }
260
261   // Look for the Objective-C modifier flags, if any.
262   // We parse these here, even if they don't apply to
263   // the conversion specifier, and then emit an error
264   // later if the conversion specifier isn't '@'.  This
265   // enables better recovery, and we don't know if
266   // these flags are applicable until later.
267   const char *ObjCModifierFlagsStart = nullptr,
268              *ObjCModifierFlagsEnd = nullptr;
269   if (*I == '[') {
270     ObjCModifierFlagsStart = I;
271     ++I;
272     auto flagStart = I;
273     for (;; ++I) {
274       ObjCModifierFlagsEnd = I;
275       if (I == E) {
276         if (Warn)
277           H.HandleIncompleteSpecifier(Start, E - Start);
278         return true;
279       }
280       // Did we find the closing ']'?
281       if (*I == ']') {
282         if (ParseObjCFlags(H, FS, flagStart, I, Warn))
283           return true;
284         ++I;
285         break;
286       }
287       // There are no separators defined yet for multiple
288       // Objective-C modifier flags.  When those are
289       // defined, this is the place to check.
290     }
291   }
292
293   if (*I == '\0') {
294     // Detect spurious null characters, which are likely errors.
295     H.HandleNullChar(I);
296     return true;
297   }
298
299   // Finally, look for the conversion specifier.
300   const char *conversionPosition = I++;
301   ConversionSpecifier::Kind k = ConversionSpecifier::InvalidSpecifier;
302   switch (*conversionPosition) {
303     default:
304       break;
305     // C99: 7.19.6.1 (section 8).
306     case '%': k = ConversionSpecifier::PercentArg;   break;
307     case 'A': k = ConversionSpecifier::AArg; break;
308     case 'E': k = ConversionSpecifier::EArg; break;
309     case 'F': k = ConversionSpecifier::FArg; break;
310     case 'G': k = ConversionSpecifier::GArg; break;
311     case 'X': k = ConversionSpecifier::XArg; break;
312     case 'a': k = ConversionSpecifier::aArg; break;
313     case 'c': k = ConversionSpecifier::cArg; break;
314     case 'd': k = ConversionSpecifier::dArg; break;
315     case 'e': k = ConversionSpecifier::eArg; break;
316     case 'f': k = ConversionSpecifier::fArg; break;
317     case 'g': k = ConversionSpecifier::gArg; break;
318     case 'i': k = ConversionSpecifier::iArg; break;
319     case 'n': k = ConversionSpecifier::nArg; break;
320     case 'o': k = ConversionSpecifier::oArg; break;
321     case 'p': k = ConversionSpecifier::pArg; break;
322     case 's': k = ConversionSpecifier::sArg; break;
323     case 'u': k = ConversionSpecifier::uArg; break;
324     case 'x': k = ConversionSpecifier::xArg; break;
325     // POSIX specific.
326     case 'C': k = ConversionSpecifier::CArg; break;
327     case 'S': k = ConversionSpecifier::SArg; break;
328     // Apple extension for os_log
329     case 'P':
330       k = ConversionSpecifier::PArg;
331       break;
332     // Objective-C.
333     case '@': k = ConversionSpecifier::ObjCObjArg; break;
334     // Glibc specific.
335     case 'm': k = ConversionSpecifier::PrintErrno; break;
336     // FreeBSD kernel specific.
337     case 'b':
338       if (isFreeBSDKPrintf)
339         k = ConversionSpecifier::FreeBSDbArg; // int followed by char *
340       break;
341     case 'r':
342       if (isFreeBSDKPrintf)
343         k = ConversionSpecifier::FreeBSDrArg; // int
344       break;
345     case 'y':
346       if (isFreeBSDKPrintf)
347         k = ConversionSpecifier::FreeBSDyArg; // int
348       break;
349     // Apple-specific.
350     case 'D':
351       if (isFreeBSDKPrintf)
352         k = ConversionSpecifier::FreeBSDDArg; // void * followed by char *
353       else if (Target.getTriple().isOSDarwin())
354         k = ConversionSpecifier::DArg;
355       break;
356     case 'O':
357       if (Target.getTriple().isOSDarwin())
358         k = ConversionSpecifier::OArg;
359       break;
360     case 'U':
361       if (Target.getTriple().isOSDarwin())
362         k = ConversionSpecifier::UArg;
363       break;
364     // MS specific.
365     case 'Z':
366       if (Target.getTriple().isOSMSVCRT())
367         k = ConversionSpecifier::ZArg;
368       break;
369   }
370
371   // Check to see if we used the Objective-C modifier flags with
372   // a conversion specifier other than '@'.
373   if (k != ConversionSpecifier::ObjCObjArg &&
374       k != ConversionSpecifier::InvalidSpecifier &&
375       ObjCModifierFlagsStart) {
376     H.HandleObjCFlagsWithNonObjCConversion(ObjCModifierFlagsStart,
377                                            ObjCModifierFlagsEnd + 1,
378                                            conversionPosition);
379     return true;
380   }
381
382   PrintfConversionSpecifier CS(conversionPosition, k);
383   FS.setConversionSpecifier(CS);
384   if (CS.consumesDataArgument() && !FS.usesPositionalArg())
385     FS.setArgIndex(argIndex++);
386   // FreeBSD kernel specific.
387   if (k == ConversionSpecifier::FreeBSDbArg ||
388       k == ConversionSpecifier::FreeBSDDArg)
389     argIndex++;
390
391   if (k == ConversionSpecifier::InvalidSpecifier) {
392     unsigned Len = I - Start;
393     if (ParseUTF8InvalidSpecifier(Start, E, Len)) {
394       CS.setEndScanList(Start + Len);
395       FS.setConversionSpecifier(CS);
396     }
397     // Assume the conversion takes one argument.
398     return !H.HandleInvalidPrintfConversionSpecifier(FS, Start, Len);
399   }
400   return PrintfSpecifierResult(Start, FS);
401 }
402
403 bool clang::analyze_format_string::ParsePrintfString(FormatStringHandler &H,
404                                                      const char *I,
405                                                      const char *E,
406                                                      const LangOptions &LO,
407                                                      const TargetInfo &Target,
408                                                      bool isFreeBSDKPrintf) {
409
410   unsigned argIndex = 0;
411
412   // Keep looking for a format specifier until we have exhausted the string.
413   while (I != E) {
414     const PrintfSpecifierResult &FSR = ParsePrintfSpecifier(H, I, E, argIndex,
415                                                             LO, Target, true,
416                                                             isFreeBSDKPrintf);
417     // Did a fail-stop error of any kind occur when parsing the specifier?
418     // If so, don't do any more processing.
419     if (FSR.shouldStop())
420       return true;
421     // Did we exhaust the string or encounter an error that
422     // we can recover from?
423     if (!FSR.hasValue())
424       continue;
425     // We have a format specifier.  Pass it to the callback.
426     if (!H.HandlePrintfSpecifier(FSR.getValue(), FSR.getStart(),
427                                  I - FSR.getStart()))
428       return true;
429   }
430   assert(I == E && "Format string not exhausted");
431   return false;
432 }
433
434 bool clang::analyze_format_string::ParseFormatStringHasSArg(const char *I,
435                                                             const char *E,
436                                                             const LangOptions &LO,
437                                                             const TargetInfo &Target) {
438
439   unsigned argIndex = 0;
440
441   // Keep looking for a %s format specifier until we have exhausted the string.
442   FormatStringHandler H;
443   while (I != E) {
444     const PrintfSpecifierResult &FSR = ParsePrintfSpecifier(H, I, E, argIndex,
445                                                             LO, Target, false,
446                                                             false);
447     // Did a fail-stop error of any kind occur when parsing the specifier?
448     // If so, don't do any more processing.
449     if (FSR.shouldStop())
450       return false;
451     // Did we exhaust the string or encounter an error that
452     // we can recover from?
453     if (!FSR.hasValue())
454       continue;
455     const analyze_printf::PrintfSpecifier &FS = FSR.getValue();
456     // Return true if this a %s format specifier.
457     if (FS.getConversionSpecifier().getKind() == ConversionSpecifier::Kind::sArg)
458       return true;
459   }
460   return false;
461 }
462
463 //===----------------------------------------------------------------------===//
464 // Methods on PrintfSpecifier.
465 //===----------------------------------------------------------------------===//
466
467 ArgType PrintfSpecifier::getScalarArgType(ASTContext &Ctx,
468                                           bool IsObjCLiteral) const {
469   if (CS.getKind() == ConversionSpecifier::cArg)
470     switch (LM.getKind()) {
471       case LengthModifier::None:
472         return Ctx.IntTy;
473       case LengthModifier::AsLong:
474       case LengthModifier::AsWide:
475         return ArgType(ArgType::WIntTy, "wint_t");
476       case LengthModifier::AsShort:
477         if (Ctx.getTargetInfo().getTriple().isOSMSVCRT())
478           return Ctx.IntTy;
479         LLVM_FALLTHROUGH;
480       default:
481         return ArgType::Invalid();
482     }
483
484   if (CS.isIntArg())
485     switch (LM.getKind()) {
486       case LengthModifier::AsLongDouble:
487         // GNU extension.
488         return Ctx.LongLongTy;
489       case LengthModifier::None:
490         return Ctx.IntTy;
491       case LengthModifier::AsInt32:
492         return ArgType(Ctx.IntTy, "__int32");
493       case LengthModifier::AsChar: return ArgType::AnyCharTy;
494       case LengthModifier::AsShort: return Ctx.ShortTy;
495       case LengthModifier::AsLong: return Ctx.LongTy;
496       case LengthModifier::AsLongLong:
497       case LengthModifier::AsQuad:
498         return Ctx.LongLongTy;
499       case LengthModifier::AsInt64:
500         return ArgType(Ctx.LongLongTy, "__int64");
501       case LengthModifier::AsIntMax:
502         return ArgType(Ctx.getIntMaxType(), "intmax_t");
503       case LengthModifier::AsSizeT:
504         return ArgType::makeSizeT(ArgType(Ctx.getSignedSizeType(), "ssize_t"));
505       case LengthModifier::AsInt3264:
506         return Ctx.getTargetInfo().getTriple().isArch64Bit()
507                    ? ArgType(Ctx.LongLongTy, "__int64")
508                    : ArgType(Ctx.IntTy, "__int32");
509       case LengthModifier::AsPtrDiff:
510         return ArgType::makePtrdiffT(
511             ArgType(Ctx.getPointerDiffType(), "ptrdiff_t"));
512       case LengthModifier::AsAllocate:
513       case LengthModifier::AsMAllocate:
514       case LengthModifier::AsWide:
515         return ArgType::Invalid();
516     }
517
518   if (CS.isUIntArg())
519     switch (LM.getKind()) {
520       case LengthModifier::AsLongDouble:
521         // GNU extension.
522         return Ctx.UnsignedLongLongTy;
523       case LengthModifier::None:
524         return Ctx.UnsignedIntTy;
525       case LengthModifier::AsInt32:
526         return ArgType(Ctx.UnsignedIntTy, "unsigned __int32");
527       case LengthModifier::AsChar: return Ctx.UnsignedCharTy;
528       case LengthModifier::AsShort: return Ctx.UnsignedShortTy;
529       case LengthModifier::AsLong: return Ctx.UnsignedLongTy;
530       case LengthModifier::AsLongLong:
531       case LengthModifier::AsQuad:
532         return Ctx.UnsignedLongLongTy;
533       case LengthModifier::AsInt64:
534         return ArgType(Ctx.UnsignedLongLongTy, "unsigned __int64");
535       case LengthModifier::AsIntMax:
536         return ArgType(Ctx.getUIntMaxType(), "uintmax_t");
537       case LengthModifier::AsSizeT:
538         return ArgType::makeSizeT(ArgType(Ctx.getSizeType(), "size_t"));
539       case LengthModifier::AsInt3264:
540         return Ctx.getTargetInfo().getTriple().isArch64Bit()
541                    ? ArgType(Ctx.UnsignedLongLongTy, "unsigned __int64")
542                    : ArgType(Ctx.UnsignedIntTy, "unsigned __int32");
543       case LengthModifier::AsPtrDiff:
544         return ArgType::makePtrdiffT(
545             ArgType(Ctx.getUnsignedPointerDiffType(), "unsigned ptrdiff_t"));
546       case LengthModifier::AsAllocate:
547       case LengthModifier::AsMAllocate:
548       case LengthModifier::AsWide:
549         return ArgType::Invalid();
550     }
551
552   if (CS.isDoubleArg()) {
553     if (LM.getKind() == LengthModifier::AsLongDouble)
554       return Ctx.LongDoubleTy;
555     return Ctx.DoubleTy;
556   }
557
558   if (CS.getKind() == ConversionSpecifier::nArg) {
559     switch (LM.getKind()) {
560       case LengthModifier::None:
561         return ArgType::PtrTo(Ctx.IntTy);
562       case LengthModifier::AsChar:
563         return ArgType::PtrTo(Ctx.SignedCharTy);
564       case LengthModifier::AsShort:
565         return ArgType::PtrTo(Ctx.ShortTy);
566       case LengthModifier::AsLong:
567         return ArgType::PtrTo(Ctx.LongTy);
568       case LengthModifier::AsLongLong:
569       case LengthModifier::AsQuad:
570         return ArgType::PtrTo(Ctx.LongLongTy);
571       case LengthModifier::AsIntMax:
572         return ArgType::PtrTo(ArgType(Ctx.getIntMaxType(), "intmax_t"));
573       case LengthModifier::AsSizeT:
574         return ArgType::PtrTo(ArgType(Ctx.getSignedSizeType(), "ssize_t"));
575       case LengthModifier::AsPtrDiff:
576         return ArgType::PtrTo(ArgType(Ctx.getPointerDiffType(), "ptrdiff_t"));
577       case LengthModifier::AsLongDouble:
578         return ArgType(); // FIXME: Is this a known extension?
579       case LengthModifier::AsAllocate:
580       case LengthModifier::AsMAllocate:
581       case LengthModifier::AsInt32:
582       case LengthModifier::AsInt3264:
583       case LengthModifier::AsInt64:
584       case LengthModifier::AsWide:
585         return ArgType::Invalid();
586     }
587   }
588
589   switch (CS.getKind()) {
590     case ConversionSpecifier::sArg:
591       if (LM.getKind() == LengthModifier::AsWideChar) {
592         if (IsObjCLiteral)
593           return ArgType(Ctx.getPointerType(Ctx.UnsignedShortTy.withConst()),
594                          "const unichar *");
595         return ArgType(ArgType::WCStrTy, "wchar_t *");
596       }
597       if (LM.getKind() == LengthModifier::AsWide)
598         return ArgType(ArgType::WCStrTy, "wchar_t *");
599       return ArgType::CStrTy;
600     case ConversionSpecifier::SArg:
601       if (IsObjCLiteral)
602         return ArgType(Ctx.getPointerType(Ctx.UnsignedShortTy.withConst()),
603                        "const unichar *");
604       if (Ctx.getTargetInfo().getTriple().isOSMSVCRT() &&
605           LM.getKind() == LengthModifier::AsShort)
606         return ArgType::CStrTy;
607       return ArgType(ArgType::WCStrTy, "wchar_t *");
608     case ConversionSpecifier::CArg:
609       if (IsObjCLiteral)
610         return ArgType(Ctx.UnsignedShortTy, "unichar");
611       if (Ctx.getTargetInfo().getTriple().isOSMSVCRT() &&
612           LM.getKind() == LengthModifier::AsShort)
613         return Ctx.IntTy;
614       return ArgType(Ctx.WideCharTy, "wchar_t");
615     case ConversionSpecifier::pArg:
616     case ConversionSpecifier::PArg:
617       return ArgType::CPointerTy;
618     case ConversionSpecifier::ObjCObjArg:
619       return ArgType::ObjCPointerTy;
620     default:
621       break;
622   }
623
624   // FIXME: Handle other cases.
625   return ArgType();
626 }
627
628
629 ArgType PrintfSpecifier::getArgType(ASTContext &Ctx,
630                                     bool IsObjCLiteral) const {
631   const PrintfConversionSpecifier &CS = getConversionSpecifier();
632
633   if (!CS.consumesDataArgument())
634     return ArgType::Invalid();
635
636   ArgType ScalarTy = getScalarArgType(Ctx, IsObjCLiteral);
637   if (!ScalarTy.isValid() || VectorNumElts.isInvalid())
638     return ScalarTy;
639
640   return ScalarTy.makeVectorType(Ctx, VectorNumElts.getConstantAmount());
641 }
642
643 bool PrintfSpecifier::fixType(QualType QT, const LangOptions &LangOpt,
644                               ASTContext &Ctx, bool IsObjCLiteral) {
645   // %n is different from other conversion specifiers; don't try to fix it.
646   if (CS.getKind() == ConversionSpecifier::nArg)
647     return false;
648
649   // Handle Objective-C objects first. Note that while the '%@' specifier will
650   // not warn for structure pointer or void pointer arguments (because that's
651   // how CoreFoundation objects are implemented), we only show a fixit for '%@'
652   // if we know it's an object (block, id, class, or __attribute__((NSObject))).
653   if (QT->isObjCRetainableType()) {
654     if (!IsObjCLiteral)
655       return false;
656
657     CS.setKind(ConversionSpecifier::ObjCObjArg);
658
659     // Disable irrelevant flags
660     HasThousandsGrouping = false;
661     HasPlusPrefix = false;
662     HasSpacePrefix = false;
663     HasAlternativeForm = false;
664     HasLeadingZeroes = false;
665     Precision.setHowSpecified(OptionalAmount::NotSpecified);
666     LM.setKind(LengthModifier::None);
667
668     return true;
669   }
670
671   // Handle strings next (char *, wchar_t *)
672   if (QT->isPointerType() && (QT->getPointeeType()->isAnyCharacterType())) {
673     CS.setKind(ConversionSpecifier::sArg);
674
675     // Disable irrelevant flags
676     HasAlternativeForm = 0;
677     HasLeadingZeroes = 0;
678
679     // Set the long length modifier for wide characters
680     if (QT->getPointeeType()->isWideCharType())
681       LM.setKind(LengthModifier::AsWideChar);
682     else
683       LM.setKind(LengthModifier::None);
684
685     return true;
686   }
687
688   // If it's an enum, get its underlying type.
689   if (const EnumType *ETy = QT->getAs<EnumType>())
690     QT = ETy->getDecl()->getIntegerType();
691
692   const BuiltinType *BT = QT->getAs<BuiltinType>();
693   if (!BT) {
694     const VectorType *VT = QT->getAs<VectorType>();
695     if (VT) {
696       QT = VT->getElementType();
697       BT = QT->getAs<BuiltinType>();
698       VectorNumElts = OptionalAmount(VT->getNumElements());
699     }
700   }
701
702   // We can only work with builtin types.
703   if (!BT)
704     return false;
705
706   // Set length modifier
707   switch (BT->getKind()) {
708   case BuiltinType::Bool:
709   case BuiltinType::WChar_U:
710   case BuiltinType::WChar_S:
711   case BuiltinType::Char8: // FIXME: Treat like 'char'?
712   case BuiltinType::Char16:
713   case BuiltinType::Char32:
714   case BuiltinType::UInt128:
715   case BuiltinType::Int128:
716   case BuiltinType::Half:
717   case BuiltinType::Float16:
718   case BuiltinType::Float128:
719   case BuiltinType::ShortAccum:
720   case BuiltinType::Accum:
721   case BuiltinType::LongAccum:
722   case BuiltinType::UShortAccum:
723   case BuiltinType::UAccum:
724   case BuiltinType::ULongAccum:
725   case BuiltinType::ShortFract:
726   case BuiltinType::Fract:
727   case BuiltinType::LongFract:
728   case BuiltinType::UShortFract:
729   case BuiltinType::UFract:
730   case BuiltinType::ULongFract:
731   case BuiltinType::SatShortAccum:
732   case BuiltinType::SatAccum:
733   case BuiltinType::SatLongAccum:
734   case BuiltinType::SatUShortAccum:
735   case BuiltinType::SatUAccum:
736   case BuiltinType::SatULongAccum:
737   case BuiltinType::SatShortFract:
738   case BuiltinType::SatFract:
739   case BuiltinType::SatLongFract:
740   case BuiltinType::SatUShortFract:
741   case BuiltinType::SatUFract:
742   case BuiltinType::SatULongFract:
743     // Various types which are non-trivial to correct.
744     return false;
745
746 #define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \
747   case BuiltinType::Id:
748 #include "clang/Basic/OpenCLImageTypes.def"
749 #define EXT_OPAQUE_TYPE(ExtType, Id, Ext) \
750   case BuiltinType::Id:
751 #include "clang/Basic/OpenCLExtensionTypes.def"
752 #define SIGNED_TYPE(Id, SingletonId)
753 #define UNSIGNED_TYPE(Id, SingletonId)
754 #define FLOATING_TYPE(Id, SingletonId)
755 #define BUILTIN_TYPE(Id, SingletonId) \
756   case BuiltinType::Id:
757 #include "clang/AST/BuiltinTypes.def"
758     // Misc other stuff which doesn't make sense here.
759     return false;
760
761   case BuiltinType::UInt:
762   case BuiltinType::Int:
763   case BuiltinType::Float:
764   case BuiltinType::Double:
765     LM.setKind(LengthModifier::None);
766     break;
767
768   case BuiltinType::Char_U:
769   case BuiltinType::UChar:
770   case BuiltinType::Char_S:
771   case BuiltinType::SChar:
772     LM.setKind(LengthModifier::AsChar);
773     break;
774
775   case BuiltinType::Short:
776   case BuiltinType::UShort:
777     LM.setKind(LengthModifier::AsShort);
778     break;
779
780   case BuiltinType::Long:
781   case BuiltinType::ULong:
782     LM.setKind(LengthModifier::AsLong);
783     break;
784
785   case BuiltinType::LongLong:
786   case BuiltinType::ULongLong:
787     LM.setKind(LengthModifier::AsLongLong);
788     break;
789
790   case BuiltinType::LongDouble:
791     LM.setKind(LengthModifier::AsLongDouble);
792     break;
793   }
794
795   // Handle size_t, ptrdiff_t, etc. that have dedicated length modifiers in C99.
796   if (isa<TypedefType>(QT) && (LangOpt.C99 || LangOpt.CPlusPlus11))
797     namedTypeToLengthModifier(QT, LM);
798
799   // If fixing the length modifier was enough, we might be done.
800   if (hasValidLengthModifier(Ctx.getTargetInfo())) {
801     // If we're going to offer a fix anyway, make sure the sign matches.
802     switch (CS.getKind()) {
803     case ConversionSpecifier::uArg:
804     case ConversionSpecifier::UArg:
805       if (QT->isSignedIntegerType())
806         CS.setKind(clang::analyze_format_string::ConversionSpecifier::dArg);
807       break;
808     case ConversionSpecifier::dArg:
809     case ConversionSpecifier::DArg:
810     case ConversionSpecifier::iArg:
811       if (QT->isUnsignedIntegerType() && !HasPlusPrefix)
812         CS.setKind(clang::analyze_format_string::ConversionSpecifier::uArg);
813       break;
814     default:
815       // Other specifiers do not have signed/unsigned variants.
816       break;
817     }
818
819     const analyze_printf::ArgType &ATR = getArgType(Ctx, IsObjCLiteral);
820     if (ATR.isValid() && ATR.matchesType(Ctx, QT))
821       return true;
822   }
823
824   // Set conversion specifier and disable any flags which do not apply to it.
825   // Let typedefs to char fall through to int, as %c is silly for uint8_t.
826   if (!isa<TypedefType>(QT) && QT->isCharType()) {
827     CS.setKind(ConversionSpecifier::cArg);
828     LM.setKind(LengthModifier::None);
829     Precision.setHowSpecified(OptionalAmount::NotSpecified);
830     HasAlternativeForm = 0;
831     HasLeadingZeroes = 0;
832     HasPlusPrefix = 0;
833   }
834   // Test for Floating type first as LongDouble can pass isUnsignedIntegerType
835   else if (QT->isRealFloatingType()) {
836     CS.setKind(ConversionSpecifier::fArg);
837   }
838   else if (QT->isSignedIntegerType()) {
839     CS.setKind(ConversionSpecifier::dArg);
840     HasAlternativeForm = 0;
841   }
842   else if (QT->isUnsignedIntegerType()) {
843     CS.setKind(ConversionSpecifier::uArg);
844     HasAlternativeForm = 0;
845     HasPlusPrefix = 0;
846   } else {
847     llvm_unreachable("Unexpected type");
848   }
849
850   return true;
851 }
852
853 void PrintfSpecifier::toString(raw_ostream &os) const {
854   // Whilst some features have no defined order, we are using the order
855   // appearing in the C99 standard (ISO/IEC 9899:1999 (E) 7.19.6.1)
856   os << "%";
857
858   // Positional args
859   if (usesPositionalArg()) {
860     os << getPositionalArgIndex() << "$";
861   }
862
863   // Conversion flags
864   if (IsLeftJustified)    os << "-";
865   if (HasPlusPrefix)      os << "+";
866   if (HasSpacePrefix)     os << " ";
867   if (HasAlternativeForm) os << "#";
868   if (HasLeadingZeroes)   os << "0";
869
870   // Minimum field width
871   FieldWidth.toString(os);
872   // Precision
873   Precision.toString(os);
874
875   // Vector modifier
876   if (!VectorNumElts.isInvalid())
877     os << 'v' << VectorNumElts.getConstantAmount();
878
879   // Length modifier
880   os << LM.toString();
881   // Conversion specifier
882   os << CS.toString();
883 }
884
885 bool PrintfSpecifier::hasValidPlusPrefix() const {
886   if (!HasPlusPrefix)
887     return true;
888
889   // The plus prefix only makes sense for signed conversions
890   switch (CS.getKind()) {
891   case ConversionSpecifier::dArg:
892   case ConversionSpecifier::DArg:
893   case ConversionSpecifier::iArg:
894   case ConversionSpecifier::fArg:
895   case ConversionSpecifier::FArg:
896   case ConversionSpecifier::eArg:
897   case ConversionSpecifier::EArg:
898   case ConversionSpecifier::gArg:
899   case ConversionSpecifier::GArg:
900   case ConversionSpecifier::aArg:
901   case ConversionSpecifier::AArg:
902   case ConversionSpecifier::FreeBSDrArg:
903   case ConversionSpecifier::FreeBSDyArg:
904     return true;
905
906   default:
907     return false;
908   }
909 }
910
911 bool PrintfSpecifier::hasValidAlternativeForm() const {
912   if (!HasAlternativeForm)
913     return true;
914
915   // Alternate form flag only valid with the oxXaAeEfFgG conversions
916   switch (CS.getKind()) {
917   case ConversionSpecifier::oArg:
918   case ConversionSpecifier::OArg:
919   case ConversionSpecifier::xArg:
920   case ConversionSpecifier::XArg:
921   case ConversionSpecifier::aArg:
922   case ConversionSpecifier::AArg:
923   case ConversionSpecifier::eArg:
924   case ConversionSpecifier::EArg:
925   case ConversionSpecifier::fArg:
926   case ConversionSpecifier::FArg:
927   case ConversionSpecifier::gArg:
928   case ConversionSpecifier::GArg:
929   case ConversionSpecifier::FreeBSDrArg:
930   case ConversionSpecifier::FreeBSDyArg:
931     return true;
932
933   default:
934     return false;
935   }
936 }
937
938 bool PrintfSpecifier::hasValidLeadingZeros() const {
939   if (!HasLeadingZeroes)
940     return true;
941
942   // Leading zeroes flag only valid with the diouxXaAeEfFgG conversions
943   switch (CS.getKind()) {
944   case ConversionSpecifier::dArg:
945   case ConversionSpecifier::DArg:
946   case ConversionSpecifier::iArg:
947   case ConversionSpecifier::oArg:
948   case ConversionSpecifier::OArg:
949   case ConversionSpecifier::uArg:
950   case ConversionSpecifier::UArg:
951   case ConversionSpecifier::xArg:
952   case ConversionSpecifier::XArg:
953   case ConversionSpecifier::aArg:
954   case ConversionSpecifier::AArg:
955   case ConversionSpecifier::eArg:
956   case ConversionSpecifier::EArg:
957   case ConversionSpecifier::fArg:
958   case ConversionSpecifier::FArg:
959   case ConversionSpecifier::gArg:
960   case ConversionSpecifier::GArg:
961   case ConversionSpecifier::FreeBSDrArg:
962   case ConversionSpecifier::FreeBSDyArg:
963     return true;
964
965   default:
966     return false;
967   }
968 }
969
970 bool PrintfSpecifier::hasValidSpacePrefix() const {
971   if (!HasSpacePrefix)
972     return true;
973
974   // The space prefix only makes sense for signed conversions
975   switch (CS.getKind()) {
976   case ConversionSpecifier::dArg:
977   case ConversionSpecifier::DArg:
978   case ConversionSpecifier::iArg:
979   case ConversionSpecifier::fArg:
980   case ConversionSpecifier::FArg:
981   case ConversionSpecifier::eArg:
982   case ConversionSpecifier::EArg:
983   case ConversionSpecifier::gArg:
984   case ConversionSpecifier::GArg:
985   case ConversionSpecifier::aArg:
986   case ConversionSpecifier::AArg:
987   case ConversionSpecifier::FreeBSDrArg:
988   case ConversionSpecifier::FreeBSDyArg:
989     return true;
990
991   default:
992     return false;
993   }
994 }
995
996 bool PrintfSpecifier::hasValidLeftJustified() const {
997   if (!IsLeftJustified)
998     return true;
999
1000   // The left justified flag is valid for all conversions except n
1001   switch (CS.getKind()) {
1002   case ConversionSpecifier::nArg:
1003     return false;
1004
1005   default:
1006     return true;
1007   }
1008 }
1009
1010 bool PrintfSpecifier::hasValidThousandsGroupingPrefix() const {
1011   if (!HasThousandsGrouping)
1012     return true;
1013
1014   switch (CS.getKind()) {
1015     case ConversionSpecifier::dArg:
1016     case ConversionSpecifier::DArg:
1017     case ConversionSpecifier::iArg:
1018     case ConversionSpecifier::uArg:
1019     case ConversionSpecifier::UArg:
1020     case ConversionSpecifier::fArg:
1021     case ConversionSpecifier::FArg:
1022     case ConversionSpecifier::gArg:
1023     case ConversionSpecifier::GArg:
1024       return true;
1025     default:
1026       return false;
1027   }
1028 }
1029
1030 bool PrintfSpecifier::hasValidPrecision() const {
1031   if (Precision.getHowSpecified() == OptionalAmount::NotSpecified)
1032     return true;
1033
1034   // Precision is only valid with the diouxXaAeEfFgGsP conversions
1035   switch (CS.getKind()) {
1036   case ConversionSpecifier::dArg:
1037   case ConversionSpecifier::DArg:
1038   case ConversionSpecifier::iArg:
1039   case ConversionSpecifier::oArg:
1040   case ConversionSpecifier::OArg:
1041   case ConversionSpecifier::uArg:
1042   case ConversionSpecifier::UArg:
1043   case ConversionSpecifier::xArg:
1044   case ConversionSpecifier::XArg:
1045   case ConversionSpecifier::aArg:
1046   case ConversionSpecifier::AArg:
1047   case ConversionSpecifier::eArg:
1048   case ConversionSpecifier::EArg:
1049   case ConversionSpecifier::fArg:
1050   case ConversionSpecifier::FArg:
1051   case ConversionSpecifier::gArg:
1052   case ConversionSpecifier::GArg:
1053   case ConversionSpecifier::sArg:
1054   case ConversionSpecifier::FreeBSDrArg:
1055   case ConversionSpecifier::FreeBSDyArg:
1056   case ConversionSpecifier::PArg:
1057     return true;
1058
1059   default:
1060     return false;
1061   }
1062 }
1063 bool PrintfSpecifier::hasValidFieldWidth() const {
1064   if (FieldWidth.getHowSpecified() == OptionalAmount::NotSpecified)
1065       return true;
1066
1067   // The field width is valid for all conversions except n
1068   switch (CS.getKind()) {
1069   case ConversionSpecifier::nArg:
1070     return false;
1071
1072   default:
1073     return true;
1074   }
1075 }