PrintfFormatString.cpp revision 339b9072e26a2a0fe796dc69c4d28d964d0ec86d
1656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project//== PrintfFormatString.cpp - Analysis of printf format strings --*- C++ -*-==//
2656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project//
3656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project//                     The LLVM Compiler Infrastructure
4656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project//
5656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project// This file is distributed under the University of Illinois Open Source
6656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project// License. See LICENSE.TXT for details.
7656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project//
8656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project//===----------------------------------------------------------------------===//
9656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project//
10656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project// Handling of format string in printf and friends.  The structure of format
11656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project// strings for fprintf() are described in C99 7.19.6.1.
12656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project//
13656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project//===----------------------------------------------------------------------===//
14656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
15656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#include "clang/Analysis/Analyses/FormatString.h"
16656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#include "FormatStringParsing.h"
17656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
18656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectusing clang::analyze_format_string::ArgTypeResult;
19656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectusing clang::analyze_format_string::FormatStringHandler;
20656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectusing clang::analyze_format_string::LengthModifier;
21656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectusing clang::analyze_format_string::OptionalAmount;
22656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectusing clang::analyze_format_string::ConversionSpecifier;
23656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectusing clang::analyze_printf::PrintfSpecifier;
24656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
25656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectusing namespace clang;
26656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
27656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projecttypedef clang::analyze_format_string::SpecifierResult<PrintfSpecifier>
28656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project        PrintfSpecifierResult;
29656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
30656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project//===----------------------------------------------------------------------===//
31656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project// Methods for parsing format strings.
32656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project//===----------------------------------------------------------------------===//
33656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
34656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectusing analyze_format_string::ParseNonPositionAmount;
35656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
36656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic bool ParsePrecision(FormatStringHandler &H, PrintfSpecifier &FS,
37656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project                           const char *Start, const char *&Beg, const char *E,
38656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project                           unsigned *argIndex) {
39656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project  if (argIndex) {
40656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    FS.setPrecision(ParseNonPositionAmount(Beg, E, *argIndex));
41656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project  } else {
42656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    const OptionalAmount Amt = ParsePositionAmount(H, Start, Beg, E,
43656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project                                           analyze_format_string::PrecisionPos);
44656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    if (Amt.isInvalid())
45656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project      return true;
46656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    FS.setPrecision(Amt);
47656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project  }
48656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project  return false;
49656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project}
50656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
51656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic PrintfSpecifierResult ParsePrintfSpecifier(FormatStringHandler &H,
52656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project                                                  const char *&Beg,
53656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project                                                  const char *E,
54656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project                                                  unsigned &argIndex,
55656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project                                                  const LangOptions &LO) {
56656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
57656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project  using namespace clang::analyze_format_string;
58656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project  using namespace clang::analyze_printf;
59221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
60656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project  const char *I = Beg;
61656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project  const char *Start = 0;
62656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project  UpdateOnReturn <const char*> UpdateBeg(Beg, I);
63656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
64656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project  // Look for a '%' character that indicates the start of a format specifier.
65656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project  for ( ; I != E ; ++I) {
66656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    char c = *I;
67656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    if (c == '\0') {
68656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project      // Detect spurious null characters, which are likely errors.
69656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project      H.HandleNullChar(I);
70656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project      return true;
71656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    }
72656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    if (c == '%') {
73656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project      Start = I++;  // Record the start of the format specifier.
74656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project      break;
75656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    }
76656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project  }
77656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
78656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project  // No format specifier found?
79656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project  if (!Start)
80656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    return false;
81656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
82656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project  if (I == E) {
83656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    // No more characters left?
84656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    H.HandleIncompleteSpecifier(Start, E - Start);
85656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    return true;
86656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project  }
87656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
88656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project  PrintfSpecifier FS;
89656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project  if (ParseArgPosition(H, FS, Start, I, E))
90656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    return true;
91656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
92656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project  if (I == E) {
93656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    // No more characters left?
94656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    H.HandleIncompleteSpecifier(Start, E - Start);
95656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    return true;
96656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project  }
97656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
98656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project  // Look for flags (if any).
99656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project  bool hasMore = true;
100656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project  for ( ; I != E; ++I) {
101656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    switch (*I) {
102656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project      default: hasMore = false; break;
103656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project      case '\'':
104656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project        // FIXME: POSIX specific.  Always accept?
105656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project        FS.setHasThousandsGrouping(I);
106656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project        break;
107656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project      case '-': FS.setIsLeftJustified(I); break;
108656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project      case '+': FS.setHasPlusPrefix(I); break;
109656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project      case ' ': FS.setHasSpacePrefix(I); break;
110656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project      case '#': FS.setHasAlternativeForm(I); break;
111656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project      case '0': FS.setHasLeadingZeros(I); break;
112656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    }
113656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    if (!hasMore)
114656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project      break;
115656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project  }
116656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
117656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project  if (I == E) {
118656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    // No more characters left?
119656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    H.HandleIncompleteSpecifier(Start, E - Start);
120656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    return true;
121656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project  }
122221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
123221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom  // Look for the field width (if any).
124221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom  if (ParseFieldWidth(H, FS, Start, I, E,
125221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom                      FS.usesPositionalArg() ? 0 : &argIndex))
126221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom    return true;
127221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
128221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom  if (I == E) {
129221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom    // No more characters left?
130221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom    H.HandleIncompleteSpecifier(Start, E - Start);
131221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom    return true;
132221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom  }
133221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
134221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom  // Look for the precision (if any).
135221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom  if (*I == '.') {
136221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom    ++I;
137221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom    if (I == E) {
138221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom      H.HandleIncompleteSpecifier(Start, E - Start);
139221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom      return true;
140221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom    }
141221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
142221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom    if (ParsePrecision(H, FS, Start, I, E,
143221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom                       FS.usesPositionalArg() ? 0 : &argIndex))
144221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom      return true;
145221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
146221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom    if (I == E) {
147221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom      // No more characters left?
148221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom      H.HandleIncompleteSpecifier(Start, E - Start);
149221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom      return true;
150221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom    }
151221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom  }
152221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
153221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom  // Look for the length modifier.
154221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom  if (ParseLengthModifier(FS, I, E, LO) && I == E) {
155221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom    // No more characters left?
156221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom    H.HandleIncompleteSpecifier(Start, E - Start);
157221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom    return true;
158221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom  }
159221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
160221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom  if (*I == '\0') {
161221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom    // Detect spurious null characters, which are likely errors.
162221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom    H.HandleNullChar(I);
163221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom    return true;
164221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom  }
165221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
166221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom  // Finally, look for the conversion specifier.
167221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom  const char *conversionPosition = I++;
168221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom  ConversionSpecifier::Kind k = ConversionSpecifier::InvalidSpecifier;
169221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom  switch (*conversionPosition) {
170221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom    default:
171221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom      break;
172221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom    // C99: 7.19.6.1 (section 8).
173221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom    case '%': k = ConversionSpecifier::PercentArg;   break;
174221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom    case 'A': k = ConversionSpecifier::AArg; break;
175221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom    case 'E': k = ConversionSpecifier::EArg; break;
176221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom    case 'F': k = ConversionSpecifier::FArg; break;
177221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom    case 'G': k = ConversionSpecifier::GArg; break;
178221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom    case 'X': k = ConversionSpecifier::XArg; break;
179221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom    case 'a': k = ConversionSpecifier::aArg; break;
180221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom    case 'c': k = ConversionSpecifier::cArg; break;
181221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom    case 'd': k = ConversionSpecifier::dArg; break;
182221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom    case 'e': k = ConversionSpecifier::eArg; break;
183221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom    case 'f': k = ConversionSpecifier::fArg; break;
184221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom    case 'g': k = ConversionSpecifier::gArg; break;
185221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom    case 'i': k = ConversionSpecifier::iArg; break;
186221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom    case 'n': k = ConversionSpecifier::nArg; break;
187221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom    case 'o': k = ConversionSpecifier::oArg; break;
188221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom    case 'p': k = ConversionSpecifier::pArg;   break;
189221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom    case 's': k = ConversionSpecifier::sArg;      break;
190221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom    case 'u': k = ConversionSpecifier::uArg; break;
191221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom    case 'x': k = ConversionSpecifier::xArg; break;
192221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom    // POSIX specific.
193221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom    case 'C': k = ConversionSpecifier::CArg; break;
194221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom    case 'S': k = ConversionSpecifier::SArg; break;
195221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom    // Objective-C.
196221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom    case '@': k = ConversionSpecifier::ObjCObjArg; break;
197221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom    // Glibc specific.
198221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom    case 'm': k = ConversionSpecifier::PrintErrno; break;
199221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom  }
200221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom  PrintfConversionSpecifier CS(conversionPosition, k);
201221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom  FS.setConversionSpecifier(CS);
202221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom  if (CS.consumesDataArgument() && !FS.usesPositionalArg())
203221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom    FS.setArgIndex(argIndex++);
204221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
205221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom  if (k == ConversionSpecifier::InvalidSpecifier) {
206221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom    // Assume the conversion takes one argument.
207221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom    return !H.HandleInvalidPrintfConversionSpecifier(FS, Start, I - Start);
208221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom  }
209221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom  return PrintfSpecifierResult(Start, FS);
210221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom}
211221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
212221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrombool clang::analyze_format_string::ParsePrintfString(FormatStringHandler &H,
213221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom                                                     const char *I,
214221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom                                                     const char *E,
215221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom                                                     const LangOptions &LO) {
216221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
217221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom  unsigned argIndex = 0;
218221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
219221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom  // Keep looking for a format specifier until we have exhausted the string.
220221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom  while (I != E) {
221221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom    const PrintfSpecifierResult &FSR = ParsePrintfSpecifier(H, I, E, argIndex,
222221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom                                                            LO);
223221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom    // Did a fail-stop error of any kind occur when parsing the specifier?
224221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom    // If so, don't do any more processing.
225221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom    if (FSR.shouldStop())
226221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom      return true;;
227221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom    // Did we exhaust the string or encounter an error that
228221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom    // we can recover from?
229221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom    if (!FSR.hasValue())
230221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom      continue;
231221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom    // We have a format specifier.  Pass it to the callback.
232221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom    if (!H.HandlePrintfSpecifier(FSR.getValue(), FSR.getStart(),
233221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom                                 I - FSR.getStart()))
234221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom      return true;
235221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom  }
236221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom  assert(I == E && "Format string not exhausted");
237221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom  return false;
238221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom}
239221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
240221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom//===----------------------------------------------------------------------===//
241221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom// Methods on PrintfSpecifier.
242221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom//===----------------------------------------------------------------------===//
243221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
244221304ee937bc0910948a8be1320cb8cc4eb6d36Brian CarlstromArgTypeResult PrintfSpecifier::getArgType(ASTContext &Ctx,
245221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom                                          bool IsObjCLiteral) const {
246221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom  const PrintfConversionSpecifier &CS = getConversionSpecifier();
247221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
248221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom  if (!CS.consumesDataArgument())
249221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom    return ArgTypeResult::Invalid();
250221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
251221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom  if (CS.getKind() == ConversionSpecifier::cArg)
252221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom    switch (LM.getKind()) {
253221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom      case LengthModifier::None: return Ctx.IntTy;
254221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom      case LengthModifier::AsLong:
255221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom        return ArgTypeResult(ArgTypeResult::WIntTy, "wint_t");
256221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom      default:
257221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom        return ArgTypeResult::Invalid();
258221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom    }
259221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
260221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom  if (CS.isIntArg())
261221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom    switch (LM.getKind()) {
262221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom      case LengthModifier::AsLongDouble:
263221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom        // GNU extension.
264221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom        return Ctx.LongLongTy;
265221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom      case LengthModifier::None: return Ctx.IntTy;
266221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom      case LengthModifier::AsChar: return ArgTypeResult::AnyCharTy;
267221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom      case LengthModifier::AsShort: return Ctx.ShortTy;
268221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom      case LengthModifier::AsLong: return Ctx.LongTy;
269221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom      case LengthModifier::AsLongLong: return Ctx.LongLongTy;
270221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom      case LengthModifier::AsIntMax:
271221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom        return ArgTypeResult(Ctx.getIntMaxType(), "intmax_t");
272221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom      case LengthModifier::AsSizeT:
273221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom        // FIXME: How to get the corresponding signed version of size_t?
274221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom        return ArgTypeResult();
275221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom      case LengthModifier::AsPtrDiff:
276221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom        return ArgTypeResult(Ctx.getPointerDiffType(), "ptrdiff_t");
277221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom      case LengthModifier::AsAllocate:
278221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom      case LengthModifier::AsMAllocate:
279221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom        return ArgTypeResult::Invalid();
280221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom    }
281221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
282221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom  if (CS.isUIntArg())
283221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom    switch (LM.getKind()) {
284221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom      case LengthModifier::AsLongDouble:
285221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom        // GNU extension.
286221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom        return Ctx.UnsignedLongLongTy;
287221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom      case LengthModifier::None: return Ctx.UnsignedIntTy;
288221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom      case LengthModifier::AsChar: return Ctx.UnsignedCharTy;
289221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom      case LengthModifier::AsShort: return Ctx.UnsignedShortTy;
290221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom      case LengthModifier::AsLong: return Ctx.UnsignedLongTy;
291221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom      case LengthModifier::AsLongLong: return Ctx.UnsignedLongLongTy;
292221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom      case LengthModifier::AsIntMax:
293221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom        return ArgTypeResult(Ctx.getUIntMaxType(), "uintmax_t");
294221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom      case LengthModifier::AsSizeT:
295221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom        return ArgTypeResult(Ctx.getSizeType(), "size_t");
296221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom      case LengthModifier::AsPtrDiff:
297221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom        // FIXME: How to get the corresponding unsigned
298221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom        // version of ptrdiff_t?
299221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom        return ArgTypeResult();
300221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom      case LengthModifier::AsAllocate:
301221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom      case LengthModifier::AsMAllocate:
302221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom        return ArgTypeResult::Invalid();
303221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom    }
304221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
305221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom  if (CS.isDoubleArg()) {
306221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom    if (LM.getKind() == LengthModifier::AsLongDouble)
307221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom      return Ctx.LongDoubleTy;
308221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom    return Ctx.DoubleTy;
309221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom  }
310221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
311221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom  switch (CS.getKind()) {
312221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom    case ConversionSpecifier::sArg:
313221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom      if (LM.getKind() == LengthModifier::AsWideChar) {
314221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom        if (IsObjCLiteral)
315221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom          return Ctx.getPointerType(Ctx.UnsignedShortTy.withConst());
316221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom        return ArgTypeResult(ArgTypeResult::WCStrTy, "wchar_t *");
317221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom      }
318221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom      return ArgTypeResult::CStrTy;
319221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom    case ConversionSpecifier::SArg:
320221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom      if (IsObjCLiteral)
321221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom        return Ctx.getPointerType(Ctx.UnsignedShortTy.withConst());
322221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom      return ArgTypeResult(ArgTypeResult::WCStrTy, "wchar_t *");
323221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom    case ConversionSpecifier::CArg:
324221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom      if (IsObjCLiteral)
325221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom        return Ctx.UnsignedShortTy;
326221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom      return ArgTypeResult(Ctx.WCharTy, "wchar_t");
327221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom    case ConversionSpecifier::pArg:
328221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom      return ArgTypeResult::CPointerTy;
329221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom    case ConversionSpecifier::ObjCObjArg:
330221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom      return ArgTypeResult::ObjCPointerTy;
331221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom    default:
332221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom      break;
333221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom  }
334221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
335221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom  // FIXME: Handle other cases.
336221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom  return ArgTypeResult();
337221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom}
338221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
339221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrombool PrintfSpecifier::fixType(QualType QT, const LangOptions &LangOpt) {
340221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom  // Handle strings first (char *, wchar_t *)
341221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom  if (QT->isPointerType() && (QT->getPointeeType()->isAnyCharacterType())) {
342221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom    CS.setKind(ConversionSpecifier::sArg);
343221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
344221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom    // Disable irrelevant flags
345221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom    HasAlternativeForm = 0;
346221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom    HasLeadingZeroes = 0;
347221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
348221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom    // Set the long length modifier for wide characters
349221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom    if (QT->getPointeeType()->isWideCharType())
350221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom      LM.setKind(LengthModifier::AsWideChar);
351221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom    else
352221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom      LM.setKind(LengthModifier::None);
353221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
354221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom    return true;
355221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom  }
356221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
357221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom  // We can only work with builtin types.
358221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom  const BuiltinType *BT = QT->getAs<BuiltinType>();
359221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom  if (!BT)
360221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom    return false;
361221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
362221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom  // Set length modifier
363221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom  switch (BT->getKind()) {
364221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom  case BuiltinType::Bool:
365221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom  case BuiltinType::WChar_U:
366221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom  case BuiltinType::WChar_S:
367221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom  case BuiltinType::Char16:
368221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom  case BuiltinType::Char32:
369221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom  case BuiltinType::UInt128:
370221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom  case BuiltinType::Int128:
371221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom  case BuiltinType::Half:
372221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom    // Various types which are non-trivial to correct.
373221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom    return false;
374221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
375221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom#define SIGNED_TYPE(Id, SingletonId)
376221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom#define UNSIGNED_TYPE(Id, SingletonId)
377221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom#define FLOATING_TYPE(Id, SingletonId)
378221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom#define BUILTIN_TYPE(Id, SingletonId) \
379221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom  case BuiltinType::Id:
380221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom#include "clang/AST/BuiltinTypes.def"
381221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom    // Misc other stuff which doesn't make sense here.
382221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom    return false;
383221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
384221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom  case BuiltinType::UInt:
385221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom  case BuiltinType::Int:
386221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom  case BuiltinType::Float:
387221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom  case BuiltinType::Double:
388221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom    LM.setKind(LengthModifier::None);
389221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom    break;
390221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
391221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom  case BuiltinType::Char_U:
392221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom  case BuiltinType::UChar:
393221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom  case BuiltinType::Char_S:
394221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom  case BuiltinType::SChar:
395221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom    LM.setKind(LengthModifier::AsChar);
396221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom    break;
397221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
398221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom  case BuiltinType::Short:
399221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom  case BuiltinType::UShort:
400221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom    LM.setKind(LengthModifier::AsShort);
401221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom    break;
402221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
403221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom  case BuiltinType::Long:
404221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom  case BuiltinType::ULong:
405221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom    LM.setKind(LengthModifier::AsLong);
406221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom    break;
407221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
408221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom  case BuiltinType::LongLong:
409221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom  case BuiltinType::ULongLong:
410221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom    LM.setKind(LengthModifier::AsLongLong);
411221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom    break;
412221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
413221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom  case BuiltinType::LongDouble:
414221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom    LM.setKind(LengthModifier::AsLongDouble);
415221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom    break;
416221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom  }
417221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
418221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom  // Handle size_t, ptrdiff_t, etc. that have dedicated length modifiers in C99.
419221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom  if (isa<TypedefType>(QT) && (LangOpt.C99 || LangOpt.CPlusPlus0x)) {
420221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom    const IdentifierInfo *Identifier = QT.getBaseTypeIdentifier();
421221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom    if (Identifier->getName() == "size_t") {
422221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom      LM.setKind(LengthModifier::AsSizeT);
423221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom    } else if (Identifier->getName() == "ssize_t") {
424221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom      // Not C99, but common in Unix.
425221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom      LM.setKind(LengthModifier::AsSizeT);
426221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom    } else if (Identifier->getName() == "intmax_t") {
427221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom      LM.setKind(LengthModifier::AsIntMax);
428221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom    } else if (Identifier->getName() == "uintmax_t") {
429221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom      LM.setKind(LengthModifier::AsIntMax);
430221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom    } else if (Identifier->getName() == "ptrdiff_t") {
431221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom      LM.setKind(LengthModifier::AsPtrDiff);
432221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom    }
433221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom  }
434221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
435221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom  // Set conversion specifier and disable any flags which do not apply to it.
436221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom  // Let typedefs to char fall through to int, as %c is silly for uint8_t.
437221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom  if (isa<TypedefType>(QT) && QT->isAnyCharacterType()) {
438221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom    CS.setKind(ConversionSpecifier::cArg);
439221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom    LM.setKind(LengthModifier::None);
440221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom    Precision.setHowSpecified(OptionalAmount::NotSpecified);
441221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom    HasAlternativeForm = 0;
442221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom    HasLeadingZeroes = 0;
443221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom    HasPlusPrefix = 0;
444221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom  }
445221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom  // Test for Floating type first as LongDouble can pass isUnsignedIntegerType
446221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom  else if (QT->isRealFloatingType()) {
447221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom    CS.setKind(ConversionSpecifier::fArg);
448221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom  }
449221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom  else if (QT->isSignedIntegerType()) {
450221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom    CS.setKind(ConversionSpecifier::dArg);
451221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom    HasAlternativeForm = 0;
452221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom  }
453221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom  else if (QT->isUnsignedIntegerType()) {
454221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom    // Preserve the original formatting, e.g. 'X', 'o'.
455221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom    if (!cast<PrintfConversionSpecifier>(CS).isUIntArg())
456221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom      CS.setKind(ConversionSpecifier::uArg);
457221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom    HasAlternativeForm = 0;
458221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom    HasPlusPrefix = 0;
459221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom  } else {
460221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom    llvm_unreachable("Unexpected type");
461221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom  }
462221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
463221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom  return true;
464221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom}
465221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
466221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstromvoid PrintfSpecifier::toString(raw_ostream &os) const {
467221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom  // Whilst some features have no defined order, we are using the order
468221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom  // appearing in the C99 standard (ISO/IEC 9899:1999 (E) 7.19.6.1)
469221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom  os << "%";
470221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
471221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom  // Positional args
472221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom  if (usesPositionalArg()) {
473221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom    os << getPositionalArgIndex() << "$";
474221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom  }
475221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
476221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom  // Conversion flags
477221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom  if (IsLeftJustified)    os << "-";
478221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom  if (HasPlusPrefix)      os << "+";
479221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom  if (HasSpacePrefix)     os << " ";
480221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom  if (HasAlternativeForm) os << "#";
481221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom  if (HasLeadingZeroes)   os << "0";
482221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
483221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom  // Minimum field width
484221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom  FieldWidth.toString(os);
485221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom  // Precision
486221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom  Precision.toString(os);
487221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom  // Length modifier
488221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom  os << LM.toString();
489221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom  // Conversion specifier
490221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom  os << CS.toString();
491221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom}
492221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
493221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrombool PrintfSpecifier::hasValidPlusPrefix() const {
494221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom  if (!HasPlusPrefix)
495221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom    return true;
496221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
497221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom  // The plus prefix only makes sense for signed conversions
498221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom  switch (CS.getKind()) {
499221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom  case ConversionSpecifier::dArg:
500221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom  case ConversionSpecifier::iArg:
501221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom  case ConversionSpecifier::fArg:
502221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom  case ConversionSpecifier::FArg:
503221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom  case ConversionSpecifier::eArg:
504221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom  case ConversionSpecifier::EArg:
505221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom  case ConversionSpecifier::gArg:
506221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom  case ConversionSpecifier::GArg:
507221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom  case ConversionSpecifier::aArg:
508221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom  case ConversionSpecifier::AArg:
509221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom    return true;
510221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
511221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom  default:
512221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom    return false;
513221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom  }
514221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom}
515221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
516221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrombool PrintfSpecifier::hasValidAlternativeForm() const {
517221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom  if (!HasAlternativeForm)
518221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom    return true;
519221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
520221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom  // Alternate form flag only valid with the oxXaAeEfFgG conversions
521221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom  switch (CS.getKind()) {
522221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom  case ConversionSpecifier::oArg:
523221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom  case ConversionSpecifier::xArg:
524221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom  case ConversionSpecifier::XArg:
525221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom  case ConversionSpecifier::aArg:
526221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom  case ConversionSpecifier::AArg:
527221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom  case ConversionSpecifier::eArg:
528221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom  case ConversionSpecifier::EArg:
529221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom  case ConversionSpecifier::fArg:
530221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom  case ConversionSpecifier::FArg:
531221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom  case ConversionSpecifier::gArg:
532221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom  case ConversionSpecifier::GArg:
533221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom    return true;
534221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
535221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom  default:
536221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom    return false;
537221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom  }
538221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom}
539221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
540221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrombool PrintfSpecifier::hasValidLeadingZeros() const {
541221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom  if (!HasLeadingZeroes)
542221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom    return true;
543221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
544221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom  // Leading zeroes flag only valid with the diouxXaAeEfFgG conversions
545221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom  switch (CS.getKind()) {
546221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom  case ConversionSpecifier::dArg:
547221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom  case ConversionSpecifier::iArg:
548221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom  case ConversionSpecifier::oArg:
549221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom  case ConversionSpecifier::uArg:
550221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom  case ConversionSpecifier::xArg:
551221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom  case ConversionSpecifier::XArg:
552221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom  case ConversionSpecifier::aArg:
553221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom  case ConversionSpecifier::AArg:
554221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom  case ConversionSpecifier::eArg:
555221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom  case ConversionSpecifier::EArg:
556221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom  case ConversionSpecifier::fArg:
557221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom  case ConversionSpecifier::FArg:
558221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom  case ConversionSpecifier::gArg:
559221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom  case ConversionSpecifier::GArg:
560221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom    return true;
561221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
562221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom  default:
563221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom    return false;
564221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom  }
565221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom}
566221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
567221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrombool PrintfSpecifier::hasValidSpacePrefix() const {
568221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom  if (!HasSpacePrefix)
569221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom    return true;
570221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
571221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom  // The space prefix only makes sense for signed conversions
572221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom  switch (CS.getKind()) {
573221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom  case ConversionSpecifier::dArg:
574221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom  case ConversionSpecifier::iArg:
575221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom  case ConversionSpecifier::fArg:
576221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom  case ConversionSpecifier::FArg:
577221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom  case ConversionSpecifier::eArg:
578221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom  case ConversionSpecifier::EArg:
579221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom  case ConversionSpecifier::gArg:
580221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom  case ConversionSpecifier::GArg:
581221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom  case ConversionSpecifier::aArg:
582221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom  case ConversionSpecifier::AArg:
583221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom    return true;
584221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
585221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom  default:
586221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom    return false;
587221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom  }
588221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom}
589221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
590221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrombool PrintfSpecifier::hasValidLeftJustified() const {
591221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom  if (!IsLeftJustified)
592221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom    return true;
593221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
594221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom  // The left justified flag is valid for all conversions except n
595221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom  switch (CS.getKind()) {
596221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom  case ConversionSpecifier::nArg:
597221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom    return false;
598221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
599221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom  default:
600221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom    return true;
601221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom  }
602221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom}
603221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
604221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrombool PrintfSpecifier::hasValidThousandsGroupingPrefix() const {
605221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom  if (!HasThousandsGrouping)
606221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom    return true;
607221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
608221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom  switch (CS.getKind()) {
609221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom    case ConversionSpecifier::dArg:
610221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom    case ConversionSpecifier::iArg:
611221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom    case ConversionSpecifier::uArg:
612221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom    case ConversionSpecifier::fArg:
613221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom    case ConversionSpecifier::FArg:
614221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom    case ConversionSpecifier::gArg:
615221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom    case ConversionSpecifier::GArg:
616221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom      return true;
617221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom    default:
618221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom      return false;
619221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom  }
620221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom}
621221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
622221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrombool PrintfSpecifier::hasValidPrecision() const {
623656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project  if (Precision.getHowSpecified() == OptionalAmount::NotSpecified)
624656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    return true;
625656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
626656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project  // Precision is only valid with the diouxXaAeEfFgGs conversions
627656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project  switch (CS.getKind()) {
628656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project  case ConversionSpecifier::dArg:
629656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project  case ConversionSpecifier::iArg:
630656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project  case ConversionSpecifier::oArg:
631656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project  case ConversionSpecifier::uArg:
632656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project  case ConversionSpecifier::xArg:
633656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project  case ConversionSpecifier::XArg:
634656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project  case ConversionSpecifier::aArg:
635656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project  case ConversionSpecifier::AArg:
636656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project  case ConversionSpecifier::eArg:
637656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project  case ConversionSpecifier::EArg:
638656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project  case ConversionSpecifier::fArg:
639656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project  case ConversionSpecifier::FArg:
640656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project  case ConversionSpecifier::gArg:
641656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project  case ConversionSpecifier::GArg:
642656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project  case ConversionSpecifier::sArg:
643656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    return true;
644221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
645221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom  default:
646221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom    return false;
647221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom  }
648221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom}
649221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrombool PrintfSpecifier::hasValidFieldWidth() const {
650221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom  if (FieldWidth.getHowSpecified() == OptionalAmount::NotSpecified)
651221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom      return true;
652221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
653221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom  // The field width is valid for all conversions except n
654221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom  switch (CS.getKind()) {
655221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom  case ConversionSpecifier::nArg:
656221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom    return false;
657221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom
658221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom  default:
659221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom    return true;
660221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom  }
661221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom}
662221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstrom