1826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek// FormatString.cpp - Common stuff for handling printf/scanf formats -*- C++ -*-
2826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek//
3826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek//                     The LLVM Compiler Infrastructure
4826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek//
5826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek// This file is distributed under the University of Illinois Open Source
6826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek// License. See LICENSE.TXT for details.
7826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek//
8826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek//===----------------------------------------------------------------------===//
9826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek//
10826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek// Shared details for processing format strings of printf and scanf
11826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek// (and friends).
12826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek//
13826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek//===----------------------------------------------------------------------===//
14826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek
15826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek#include "FormatStringParsing.h"
16d02deebce5f1b283101e035a7f5d5bab0d2068ecHans Wennborg#include "clang/Basic/LangOptions.h"
17bbb6bb4952b77e57b842b4d3096848123ae690e7Jordan Rose#include "clang/Basic/TargetInfo.h"
18826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek
19f3749f4168c5cee59627a681ca4ca6e4116d0761Hans Wennborgusing clang::analyze_format_string::ArgType;
20826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenekusing clang::analyze_format_string::FormatStringHandler;
21826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenekusing clang::analyze_format_string::FormatSpecifier;
22826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenekusing clang::analyze_format_string::LengthModifier;
23826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenekusing clang::analyze_format_string::OptionalAmount;
24826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenekusing clang::analyze_format_string::PositionContext;
25a412a499162c46211c10ad92045b9b5fd2298edeTed Kremenekusing clang::analyze_format_string::ConversionSpecifier;
26826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenekusing namespace clang;
27826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek
28826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek// Key function to FormatStringHandler.
29826a3457f737f1fc45a22954fd1bfde38160c165Ted KremenekFormatStringHandler::~FormatStringHandler() {}
30826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek
31826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek//===----------------------------------------------------------------------===//
32826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek// Functions for parsing format strings components in both printf and
33826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek// scanf format strings.
34826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek//===----------------------------------------------------------------------===//
35826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek
36826a3457f737f1fc45a22954fd1bfde38160c165Ted KremenekOptionalAmount
37826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenekclang::analyze_format_string::ParseAmount(const char *&Beg, const char *E) {
38826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek  const char *I = Beg;
39826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek  UpdateOnReturn <const char*> UpdateBeg(Beg, I);
40826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek
41826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek  unsigned accumulator = 0;
42826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek  bool hasDigits = false;
43826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek
44826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek  for ( ; I != E; ++I) {
45826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek    char c = *I;
46826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek    if (c >= '0' && c <= '9') {
47826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek      hasDigits = true;
48826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek      accumulator = (accumulator * 10) + (c - '0');
49826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek      continue;
50826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek    }
51826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek
52826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek    if (hasDigits)
53826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek      return OptionalAmount(OptionalAmount::Constant, accumulator, Beg, I - Beg,
54826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek          false);
55826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek
56826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek    break;
57826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek  }
58826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek
59826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek  return OptionalAmount();
60826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek}
61826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek
62826a3457f737f1fc45a22954fd1bfde38160c165Ted KremenekOptionalAmount
63826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenekclang::analyze_format_string::ParseNonPositionAmount(const char *&Beg,
64826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek                                                     const char *E,
65826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek                                                     unsigned &argIndex) {
66826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek  if (*Beg == '*') {
67826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek    ++Beg;
68826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek    return OptionalAmount(OptionalAmount::Arg, argIndex++, Beg, 0, false);
69826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek  }
70826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek
71826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek  return ParseAmount(Beg, E);
72826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek}
73826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek
74826a3457f737f1fc45a22954fd1bfde38160c165Ted KremenekOptionalAmount
75826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenekclang::analyze_format_string::ParsePositionAmount(FormatStringHandler &H,
76826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek                                                  const char *Start,
77826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek                                                  const char *&Beg,
78826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek                                                  const char *E,
79826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek                                                  PositionContext p) {
80826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek  if (*Beg == '*') {
81826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek    const char *I = Beg + 1;
82826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek    const OptionalAmount &Amt = ParseAmount(I, E);
83826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek
84826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek    if (Amt.getHowSpecified() == OptionalAmount::NotSpecified) {
85826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek      H.HandleInvalidPosition(Beg, I - Beg, p);
86826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek      return OptionalAmount(false);
87826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek    }
88826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek
89826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek    if (I == E) {
90826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek      // No more characters left?
91826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek      H.HandleIncompleteSpecifier(Start, E - Start);
92826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek      return OptionalAmount(false);
93826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek    }
94826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek
95826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek    assert(Amt.getHowSpecified() == OptionalAmount::Constant);
96826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek
97826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek    if (*I == '$') {
98826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek      // Handle positional arguments
99826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek
100826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek      // Special case: '*0$', since this is an easy mistake.
101826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek      if (Amt.getConstantAmount() == 0) {
102826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek        H.HandleZeroPosition(Beg, I - Beg + 1);
103826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek        return OptionalAmount(false);
104826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek      }
105826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek
106826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek      const char *Tmp = Beg;
107826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek      Beg = ++I;
108826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek
109826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek      return OptionalAmount(OptionalAmount::Arg, Amt.getConstantAmount() - 1,
110826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek                            Tmp, 0, true);
111826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek    }
112826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek
113826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek    H.HandleInvalidPosition(Beg, I - Beg, p);
114826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek    return OptionalAmount(false);
115826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek  }
116826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek
117826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek  return ParseAmount(Beg, E);
118826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek}
119826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek
120826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek
121826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenekbool
122826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenekclang::analyze_format_string::ParseFieldWidth(FormatStringHandler &H,
123826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek                                              FormatSpecifier &CS,
124826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek                                              const char *Start,
125826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek                                              const char *&Beg, const char *E,
126826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek                                              unsigned *argIndex) {
127826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek  // FIXME: Support negative field widths.
128826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek  if (argIndex) {
129826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek    CS.setFieldWidth(ParseNonPositionAmount(Beg, E, *argIndex));
130826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek  }
131826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek  else {
132826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek    const OptionalAmount Amt =
133826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek      ParsePositionAmount(H, Start, Beg, E,
134826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek                          analyze_format_string::FieldWidthPos);
135826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek
136826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek    if (Amt.isInvalid())
137826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek      return true;
138826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek    CS.setFieldWidth(Amt);
139826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek  }
140826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek  return false;
141826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek}
142826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek
143826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenekbool
144826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenekclang::analyze_format_string::ParseArgPosition(FormatStringHandler &H,
145826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek                                               FormatSpecifier &FS,
146826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek                                               const char *Start,
147826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek                                               const char *&Beg,
148826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek                                               const char *E) {
149826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek  const char *I = Beg;
150826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek
151826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek  const OptionalAmount &Amt = ParseAmount(I, E);
152826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek
153826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek  if (I == E) {
154826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek    // No more characters left?
155826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek    H.HandleIncompleteSpecifier(Start, E - Start);
156826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek    return true;
157826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek  }
158826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek
159826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek  if (Amt.getHowSpecified() == OptionalAmount::Constant && *(I++) == '$') {
160f85626453123f9691bcef13cff963f556e209c27Hans Wennborg    // Warn that positional arguments are non-standard.
161f85626453123f9691bcef13cff963f556e209c27Hans Wennborg    H.HandlePosition(Start, I - Start);
162f85626453123f9691bcef13cff963f556e209c27Hans Wennborg
163826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek    // Special case: '%0$', since this is an easy mistake.
164826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek    if (Amt.getConstantAmount() == 0) {
165826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek      H.HandleZeroPosition(Start, I - Start);
166826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek      return true;
167826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek    }
168826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek
169826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek    FS.setArgIndex(Amt.getConstantAmount() - 1);
170826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek    FS.setUsesPositionalArg();
171826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek    // Update the caller's pointer if we decided to consume
172826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek    // these characters.
173826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek    Beg = I;
174826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek    return false;
175826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek  }
176826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek
177826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek  return false;
178826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek}
179826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek
180826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenekbool
181826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenekclang::analyze_format_string::ParseLengthModifier(FormatSpecifier &FS,
182826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek                                                  const char *&I,
183d02deebce5f1b283101e035a7f5d5bab0d2068ecHans Wennborg                                                  const char *E,
184d02deebce5f1b283101e035a7f5d5bab0d2068ecHans Wennborg                                                  const LangOptions &LO,
185d02deebce5f1b283101e035a7f5d5bab0d2068ecHans Wennborg                                                  bool IsScanf) {
186826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek  LengthModifier::Kind lmKind = LengthModifier::None;
187826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek  const char *lmPosition = I;
188826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek  switch (*I) {
189826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek    default:
190826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek      return false;
191826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek    case 'h':
192826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek      ++I;
1936ca4a9ae99d65948e578d3e7d1f58ab6a947d2d7Ted Kremenek      lmKind = (I != E && *I == 'h') ? (++I, LengthModifier::AsChar)
1946ca4a9ae99d65948e578d3e7d1f58ab6a947d2d7Ted Kremenek                                     : LengthModifier::AsShort;
195826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek      break;
196826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek    case 'l':
197826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek      ++I;
1986ca4a9ae99d65948e578d3e7d1f58ab6a947d2d7Ted Kremenek      lmKind = (I != E && *I == 'l') ? (++I, LengthModifier::AsLongLong)
1996ca4a9ae99d65948e578d3e7d1f58ab6a947d2d7Ted Kremenek                                     : LengthModifier::AsLong;
200826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek      break;
201826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek    case 'j': lmKind = LengthModifier::AsIntMax;     ++I; break;
202826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek    case 'z': lmKind = LengthModifier::AsSizeT;      ++I; break;
203826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek    case 't': lmKind = LengthModifier::AsPtrDiff;    ++I; break;
204826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek    case 'L': lmKind = LengthModifier::AsLongDouble; ++I; break;
20532addd519c6699000ff79c387a1c87f0ab7c3698Hans Wennborg    case 'q': lmKind = LengthModifier::AsQuad;       ++I; break;
206d02deebce5f1b283101e035a7f5d5bab0d2068ecHans Wennborg    case 'a':
20780ad52f327b532bded5c5b0ee38779d841c6cd35Richard Smith      if (IsScanf && !LO.C99 && !LO.CPlusPlus11) {
208d02deebce5f1b283101e035a7f5d5bab0d2068ecHans Wennborg        // For scanf in C90, look at the next character to see if this should
209d02deebce5f1b283101e035a7f5d5bab0d2068ecHans Wennborg        // be parsed as the GNU extension 'a' length modifier. If not, this
210d02deebce5f1b283101e035a7f5d5bab0d2068ecHans Wennborg        // will be parsed as a conversion specifier.
211d02deebce5f1b283101e035a7f5d5bab0d2068ecHans Wennborg        ++I;
212d02deebce5f1b283101e035a7f5d5bab0d2068ecHans Wennborg        if (I != E && (*I == 's' || *I == 'S' || *I == '[')) {
213d02deebce5f1b283101e035a7f5d5bab0d2068ecHans Wennborg          lmKind = LengthModifier::AsAllocate;
214d02deebce5f1b283101e035a7f5d5bab0d2068ecHans Wennborg          break;
215d02deebce5f1b283101e035a7f5d5bab0d2068ecHans Wennborg        }
216d02deebce5f1b283101e035a7f5d5bab0d2068ecHans Wennborg        --I;
217d02deebce5f1b283101e035a7f5d5bab0d2068ecHans Wennborg      }
218d02deebce5f1b283101e035a7f5d5bab0d2068ecHans Wennborg      return false;
21937969b7e14d6a4dfd934ef6d3738cc90b832ec1dHans Wennborg    case 'm':
22037969b7e14d6a4dfd934ef6d3738cc90b832ec1dHans Wennborg      if (IsScanf) {
22137969b7e14d6a4dfd934ef6d3738cc90b832ec1dHans Wennborg        lmKind = LengthModifier::AsMAllocate;
22237969b7e14d6a4dfd934ef6d3738cc90b832ec1dHans Wennborg        ++I;
22337969b7e14d6a4dfd934ef6d3738cc90b832ec1dHans Wennborg        break;
22437969b7e14d6a4dfd934ef6d3738cc90b832ec1dHans Wennborg      }
22537969b7e14d6a4dfd934ef6d3738cc90b832ec1dHans Wennborg      return false;
226826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek  }
227826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek  LengthModifier lm(lmPosition, lmKind);
228826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek  FS.setLengthModifier(lm);
229826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek  return true;
230826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek}
231826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek
232826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek//===----------------------------------------------------------------------===//
233f3749f4168c5cee59627a681ca4ca6e4116d0761Hans Wennborg// Methods on ArgType.
234826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek//===----------------------------------------------------------------------===//
235826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek
236f3749f4168c5cee59627a681ca4ca6e4116d0761Hans Wennborgbool ArgType::matchesType(ASTContext &C, QualType argTy) const {
23758e1e54476d610d6c33ef483f216ed8a1282d35cHans Wennborg  if (Ptr) {
23858e1e54476d610d6c33ef483f216ed8a1282d35cHans Wennborg    // It has to be a pointer.
23958e1e54476d610d6c33ef483f216ed8a1282d35cHans Wennborg    const PointerType *PT = argTy->getAs<PointerType>();
24058e1e54476d610d6c33ef483f216ed8a1282d35cHans Wennborg    if (!PT)
24158e1e54476d610d6c33ef483f216ed8a1282d35cHans Wennborg      return false;
24258e1e54476d610d6c33ef483f216ed8a1282d35cHans Wennborg
24358e1e54476d610d6c33ef483f216ed8a1282d35cHans Wennborg    // We cannot write through a const qualified pointer.
24458e1e54476d610d6c33ef483f216ed8a1282d35cHans Wennborg    if (PT->getPointeeType().isConstQualified())
24558e1e54476d610d6c33ef483f216ed8a1282d35cHans Wennborg      return false;
24658e1e54476d610d6c33ef483f216ed8a1282d35cHans Wennborg
24758e1e54476d610d6c33ef483f216ed8a1282d35cHans Wennborg    argTy = PT->getPointeeType();
24858e1e54476d610d6c33ef483f216ed8a1282d35cHans Wennborg  }
24958e1e54476d610d6c33ef483f216ed8a1282d35cHans Wennborg
250826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek  switch (K) {
251826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek    case InvalidTy:
252f3749f4168c5cee59627a681ca4ca6e4116d0761Hans Wennborg      llvm_unreachable("ArgType must be valid");
253826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek
254826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek    case UnknownTy:
255826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek      return true;
2566ca4a9ae99d65948e578d3e7d1f58ab6a947d2d7Ted Kremenek
2576ca4a9ae99d65948e578d3e7d1f58ab6a947d2d7Ted Kremenek    case AnyCharTy: {
258ee0259d308e72141982a85b40863e760a8447edfJordan Rose      if (const EnumType *ETy = argTy->getAs<EnumType>())
259ee0259d308e72141982a85b40863e760a8447edfJordan Rose        argTy = ETy->getDecl()->getIntegerType();
260ee0259d308e72141982a85b40863e760a8447edfJordan Rose
2616ca4a9ae99d65948e578d3e7d1f58ab6a947d2d7Ted Kremenek      if (const BuiltinType *BT = argTy->getAs<BuiltinType>())
2626ca4a9ae99d65948e578d3e7d1f58ab6a947d2d7Ted Kremenek        switch (BT->getKind()) {
2636ca4a9ae99d65948e578d3e7d1f58ab6a947d2d7Ted Kremenek          default:
2646ca4a9ae99d65948e578d3e7d1f58ab6a947d2d7Ted Kremenek            break;
2656ca4a9ae99d65948e578d3e7d1f58ab6a947d2d7Ted Kremenek          case BuiltinType::Char_S:
2666ca4a9ae99d65948e578d3e7d1f58ab6a947d2d7Ted Kremenek          case BuiltinType::SChar:
2676ca4a9ae99d65948e578d3e7d1f58ab6a947d2d7Ted Kremenek          case BuiltinType::UChar:
2686ca4a9ae99d65948e578d3e7d1f58ab6a947d2d7Ted Kremenek          case BuiltinType::Char_U:
2696ca4a9ae99d65948e578d3e7d1f58ab6a947d2d7Ted Kremenek            return true;
2706ca4a9ae99d65948e578d3e7d1f58ab6a947d2d7Ted Kremenek        }
2716ca4a9ae99d65948e578d3e7d1f58ab6a947d2d7Ted Kremenek      return false;
2726ca4a9ae99d65948e578d3e7d1f58ab6a947d2d7Ted Kremenek    }
2736ca4a9ae99d65948e578d3e7d1f58ab6a947d2d7Ted Kremenek
274826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek    case SpecificTy: {
275ee0259d308e72141982a85b40863e760a8447edfJordan Rose      if (const EnumType *ETy = argTy->getAs<EnumType>())
276ee0259d308e72141982a85b40863e760a8447edfJordan Rose        argTy = ETy->getDecl()->getIntegerType();
277826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek      argTy = C.getCanonicalType(argTy).getUnqualifiedType();
278ee0259d308e72141982a85b40863e760a8447edfJordan Rose
279687b5df89d4ba91219df578d02087c68c09a0332Nick Lewycky      if (T == argTy)
280826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek        return true;
281dc00d8158db573f4a1f91cfaa2a89171c2e5f637Ted Kremenek      // Check for "compatible types".
2821ad35bebcc07d34202850f46b5b7be46fda1c5d1Ted Kremenek      if (const BuiltinType *BT = argTy->getAs<BuiltinType>())
283826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek        switch (BT->getKind()) {
284826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek          default:
285826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek            break;
286826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek          case BuiltinType::Char_S:
287826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek          case BuiltinType::SChar:
288dc00d8158db573f4a1f91cfaa2a89171c2e5f637Ted Kremenek          case BuiltinType::Char_U:
2891ad35bebcc07d34202850f46b5b7be46fda1c5d1Ted Kremenek          case BuiltinType::UChar:
290101d4e0c8ffbcdaaa58cddf1c20f98aa1b4501c4Hans Wennborg            return T == C.UnsignedCharTy || T == C.SignedCharTy;
291826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek          case BuiltinType::Short:
292687b5df89d4ba91219df578d02087c68c09a0332Nick Lewycky            return T == C.UnsignedShortTy;
293826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek          case BuiltinType::UShort:
294687b5df89d4ba91219df578d02087c68c09a0332Nick Lewycky            return T == C.ShortTy;
295826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek          case BuiltinType::Int:
296687b5df89d4ba91219df578d02087c68c09a0332Nick Lewycky            return T == C.UnsignedIntTy;
297826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek          case BuiltinType::UInt:
298687b5df89d4ba91219df578d02087c68c09a0332Nick Lewycky            return T == C.IntTy;
299826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek          case BuiltinType::Long:
300687b5df89d4ba91219df578d02087c68c09a0332Nick Lewycky            return T == C.UnsignedLongTy;
301826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek          case BuiltinType::ULong:
302687b5df89d4ba91219df578d02087c68c09a0332Nick Lewycky            return T == C.LongTy;
303826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek          case BuiltinType::LongLong:
304687b5df89d4ba91219df578d02087c68c09a0332Nick Lewycky            return T == C.UnsignedLongLongTy;
305826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek          case BuiltinType::ULongLong:
306687b5df89d4ba91219df578d02087c68c09a0332Nick Lewycky            return T == C.LongLongTy;
307826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek        }
308826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek      return false;
309826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek    }
310826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek
311826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek    case CStrTy: {
312826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek      const PointerType *PT = argTy->getAs<PointerType>();
313826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek      if (!PT)
314826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek        return false;
315826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek      QualType pointeeTy = PT->getPointeeType();
316826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek      if (const BuiltinType *BT = pointeeTy->getAs<BuiltinType>())
317826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek        switch (BT->getKind()) {
318826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek          case BuiltinType::Void:
319826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek          case BuiltinType::Char_U:
320826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek          case BuiltinType::UChar:
321826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek          case BuiltinType::Char_S:
322826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek          case BuiltinType::SChar:
323826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek            return true;
324826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek          default:
325826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek            break;
326826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek        }
327826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek
328826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek      return false;
329826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek    }
330826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek
331826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek    case WCStrTy: {
332826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek      const PointerType *PT = argTy->getAs<PointerType>();
333826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek      if (!PT)
334826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek        return false;
335826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek      QualType pointeeTy =
336826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek        C.getCanonicalType(PT->getPointeeType()).getUnqualifiedType();
33715f92bad58c8650b1306729744b1a1230197497aHans Wennborg      return pointeeTy == C.getWideCharType();
338826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek    }
3399325eaf08fcccbc0d038e703f570c64daacdaa31Ted Kremenek
3409325eaf08fcccbc0d038e703f570c64daacdaa31Ted Kremenek    case WIntTy: {
341392da48160bd92ceb486792780467cbfdb2d0e8cJames Molloy
3429325eaf08fcccbc0d038e703f570c64daacdaa31Ted Kremenek      QualType PromoArg =
3439325eaf08fcccbc0d038e703f570c64daacdaa31Ted Kremenek        argTy->isPromotableIntegerType()
3449325eaf08fcccbc0d038e703f570c64daacdaa31Ted Kremenek          ? C.getPromotedIntegerType(argTy) : argTy;
3459325eaf08fcccbc0d038e703f570c64daacdaa31Ted Kremenek
346392da48160bd92ceb486792780467cbfdb2d0e8cJames Molloy      QualType WInt = C.getCanonicalType(C.getWIntType()).getUnqualifiedType();
3479325eaf08fcccbc0d038e703f570c64daacdaa31Ted Kremenek      PromoArg = C.getCanonicalType(PromoArg).getUnqualifiedType();
3489325eaf08fcccbc0d038e703f570c64daacdaa31Ted Kremenek
349392da48160bd92ceb486792780467cbfdb2d0e8cJames Molloy      // If the promoted argument is the corresponding signed type of the
350392da48160bd92ceb486792780467cbfdb2d0e8cJames Molloy      // wint_t type, then it should match.
351392da48160bd92ceb486792780467cbfdb2d0e8cJames Molloy      if (PromoArg->hasSignedIntegerRepresentation() &&
352392da48160bd92ceb486792780467cbfdb2d0e8cJames Molloy          C.getCorrespondingUnsignedType(PromoArg) == WInt)
353392da48160bd92ceb486792780467cbfdb2d0e8cJames Molloy        return true;
354392da48160bd92ceb486792780467cbfdb2d0e8cJames Molloy
355392da48160bd92ceb486792780467cbfdb2d0e8cJames Molloy      return WInt == PromoArg;
3569325eaf08fcccbc0d038e703f570c64daacdaa31Ted Kremenek    }
357826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek
358826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek    case CPointerTy:
359624259984448cf19f4e94b7e31c7c32e99a39ea5Anders Carlsson      return argTy->isPointerType() || argTy->isObjCObjectPointerType() ||
360afcd1954be90965d832ae56f1413beae836c3346Ted Kremenek             argTy->isBlockPointerType() || argTy->isNullPtrType();
361826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek
362b4a3ef783cb3e9c8a927130d65385988a6aabaa3Ted Kremenek    case ObjCPointerTy: {
363b4a3ef783cb3e9c8a927130d65385988a6aabaa3Ted Kremenek      if (argTy->getAs<ObjCObjectPointerType>() ||
364b4a3ef783cb3e9c8a927130d65385988a6aabaa3Ted Kremenek          argTy->getAs<BlockPointerType>())
365b4a3ef783cb3e9c8a927130d65385988a6aabaa3Ted Kremenek        return true;
366b4a3ef783cb3e9c8a927130d65385988a6aabaa3Ted Kremenek
367b4a3ef783cb3e9c8a927130d65385988a6aabaa3Ted Kremenek      // Handle implicit toll-free bridging.
368b4a3ef783cb3e9c8a927130d65385988a6aabaa3Ted Kremenek      if (const PointerType *PT = argTy->getAs<PointerType>()) {
369b4a3ef783cb3e9c8a927130d65385988a6aabaa3Ted Kremenek        // Things such as CFTypeRef are really just opaque pointers
370b4a3ef783cb3e9c8a927130d65385988a6aabaa3Ted Kremenek        // to C structs representing CF types that can often be bridged
371b4a3ef783cb3e9c8a927130d65385988a6aabaa3Ted Kremenek        // to Objective-C objects.  Since the compiler doesn't know which
372b4a3ef783cb3e9c8a927130d65385988a6aabaa3Ted Kremenek        // structs can be toll-free bridged, we just accept them all.
373b4a3ef783cb3e9c8a927130d65385988a6aabaa3Ted Kremenek        QualType pointee = PT->getPointeeType();
374b4a3ef783cb3e9c8a927130d65385988a6aabaa3Ted Kremenek        if (pointee->getAsStructureType() || pointee->isVoidType())
375b4a3ef783cb3e9c8a927130d65385988a6aabaa3Ted Kremenek          return true;
376b4a3ef783cb3e9c8a927130d65385988a6aabaa3Ted Kremenek      }
377b4a3ef783cb3e9c8a927130d65385988a6aabaa3Ted Kremenek      return false;
378b4a3ef783cb3e9c8a927130d65385988a6aabaa3Ted Kremenek    }
379826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek  }
380826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek
381f3749f4168c5cee59627a681ca4ca6e4116d0761Hans Wennborg  llvm_unreachable("Invalid ArgType Kind!");
382826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek}
383826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek
384f3749f4168c5cee59627a681ca4ca6e4116d0761Hans WennborgQualType ArgType::getRepresentativeType(ASTContext &C) const {
38558e1e54476d610d6c33ef483f216ed8a1282d35cHans Wennborg  QualType Res;
386826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek  switch (K) {
387826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek    case InvalidTy:
388f3749f4168c5cee59627a681ca4ca6e4116d0761Hans Wennborg      llvm_unreachable("No representative type for Invalid ArgType");
389826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek    case UnknownTy:
39058e1e54476d610d6c33ef483f216ed8a1282d35cHans Wennborg      llvm_unreachable("No representative type for Unknown ArgType");
3916ca4a9ae99d65948e578d3e7d1f58ab6a947d2d7Ted Kremenek    case AnyCharTy:
39258e1e54476d610d6c33ef483f216ed8a1282d35cHans Wennborg      Res = C.CharTy;
39358e1e54476d610d6c33ef483f216ed8a1282d35cHans Wennborg      break;
394826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek    case SpecificTy:
39558e1e54476d610d6c33ef483f216ed8a1282d35cHans Wennborg      Res = T;
39658e1e54476d610d6c33ef483f216ed8a1282d35cHans Wennborg      break;
397826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek    case CStrTy:
39858e1e54476d610d6c33ef483f216ed8a1282d35cHans Wennborg      Res = C.getPointerType(C.CharTy);
39958e1e54476d610d6c33ef483f216ed8a1282d35cHans Wennborg      break;
400826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek    case WCStrTy:
40115f92bad58c8650b1306729744b1a1230197497aHans Wennborg      Res = C.getPointerType(C.getWideCharType());
40258e1e54476d610d6c33ef483f216ed8a1282d35cHans Wennborg      break;
403826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek    case ObjCPointerTy:
40458e1e54476d610d6c33ef483f216ed8a1282d35cHans Wennborg      Res = C.ObjCBuiltinIdTy;
40558e1e54476d610d6c33ef483f216ed8a1282d35cHans Wennborg      break;
406826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek    case CPointerTy:
40758e1e54476d610d6c33ef483f216ed8a1282d35cHans Wennborg      Res = C.VoidPtrTy;
40858e1e54476d610d6c33ef483f216ed8a1282d35cHans Wennborg      break;
4099325eaf08fcccbc0d038e703f570c64daacdaa31Ted Kremenek    case WIntTy: {
41058e1e54476d610d6c33ef483f216ed8a1282d35cHans Wennborg      Res = C.getWIntType();
41158e1e54476d610d6c33ef483f216ed8a1282d35cHans Wennborg      break;
4129325eaf08fcccbc0d038e703f570c64daacdaa31Ted Kremenek    }
413826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek  }
414826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek
41558e1e54476d610d6c33ef483f216ed8a1282d35cHans Wennborg  if (Ptr)
41658e1e54476d610d6c33ef483f216ed8a1282d35cHans Wennborg    Res = C.getPointerType(Res);
41758e1e54476d610d6c33ef483f216ed8a1282d35cHans Wennborg  return Res;
418826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek}
419826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek
420f3749f4168c5cee59627a681ca4ca6e4116d0761Hans Wennborgstd::string ArgType::getRepresentativeTypeName(ASTContext &C) const {
421f4f0c6095d1f481b94c6821c65e3bf1c9df42af7Hans Wennborg  std::string S = getRepresentativeType(C).getAsString();
42258e1e54476d610d6c33ef483f216ed8a1282d35cHans Wennborg
42358e1e54476d610d6c33ef483f216ed8a1282d35cHans Wennborg  std::string Alias;
42458e1e54476d610d6c33ef483f216ed8a1282d35cHans Wennborg  if (Name) {
42558e1e54476d610d6c33ef483f216ed8a1282d35cHans Wennborg    // Use a specific name for this type, e.g. "size_t".
42658e1e54476d610d6c33ef483f216ed8a1282d35cHans Wennborg    Alias = Name;
42758e1e54476d610d6c33ef483f216ed8a1282d35cHans Wennborg    if (Ptr) {
42858e1e54476d610d6c33ef483f216ed8a1282d35cHans Wennborg      // If ArgType is actually a pointer to T, append an asterisk.
42958e1e54476d610d6c33ef483f216ed8a1282d35cHans Wennborg      Alias += (Alias[Alias.size()-1] == '*') ? "*" : " *";
43058e1e54476d610d6c33ef483f216ed8a1282d35cHans Wennborg    }
43158e1e54476d610d6c33ef483f216ed8a1282d35cHans Wennborg    // If Alias is the same as the underlying type, e.g. wchar_t, then drop it.
43258e1e54476d610d6c33ef483f216ed8a1282d35cHans Wennborg    if (S == Alias)
43358e1e54476d610d6c33ef483f216ed8a1282d35cHans Wennborg      Alias.clear();
43458e1e54476d610d6c33ef483f216ed8a1282d35cHans Wennborg  }
43558e1e54476d610d6c33ef483f216ed8a1282d35cHans Wennborg
43658e1e54476d610d6c33ef483f216ed8a1282d35cHans Wennborg  if (!Alias.empty())
43758e1e54476d610d6c33ef483f216ed8a1282d35cHans Wennborg    return std::string("'") + Alias + "' (aka '" + S + "')";
438f4f0c6095d1f481b94c6821c65e3bf1c9df42af7Hans Wennborg  return std::string("'") + S + "'";
439a792aff1c7de253b89c473fdb7eef4a5bba83aecHans Wennborg}
440a792aff1c7de253b89c473fdb7eef4a5bba83aecHans Wennborg
441a792aff1c7de253b89c473fdb7eef4a5bba83aecHans Wennborg
442826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek//===----------------------------------------------------------------------===//
443826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek// Methods on OptionalAmount.
444826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek//===----------------------------------------------------------------------===//
445826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek
446f3749f4168c5cee59627a681ca4ca6e4116d0761Hans WennborgArgType
447826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenekanalyze_format_string::OptionalAmount::getArgType(ASTContext &Ctx) const {
448826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek  return Ctx.IntTy;
449826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek}
450826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek
451826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek//===----------------------------------------------------------------------===//
452826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek// Methods on LengthModifier.
453826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek//===----------------------------------------------------------------------===//
454826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek
455826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenekconst char *
456826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenekanalyze_format_string::LengthModifier::toString() const {
457826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek  switch (kind) {
458826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek  case AsChar:
459826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek    return "hh";
460826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek  case AsShort:
461826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek    return "h";
462826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek  case AsLong: // or AsWideChar
463826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek    return "l";
464826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek  case AsLongLong:
465826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek    return "ll";
46632addd519c6699000ff79c387a1c87f0ab7c3698Hans Wennborg  case AsQuad:
46732addd519c6699000ff79c387a1c87f0ab7c3698Hans Wennborg    return "q";
468826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek  case AsIntMax:
469826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek    return "j";
470826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek  case AsSizeT:
471826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek    return "z";
472826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek  case AsPtrDiff:
473826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek    return "t";
474826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek  case AsLongDouble:
475826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek    return "L";
476d02deebce5f1b283101e035a7f5d5bab0d2068ecHans Wennborg  case AsAllocate:
477d02deebce5f1b283101e035a7f5d5bab0d2068ecHans Wennborg    return "a";
47837969b7e14d6a4dfd934ef6d3738cc90b832ec1dHans Wennborg  case AsMAllocate:
47937969b7e14d6a4dfd934ef6d3738cc90b832ec1dHans Wennborg    return "m";
480826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek  case None:
481826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek    return "";
482826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek  }
483826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek  return NULL;
484826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek}
485826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek
486826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek//===----------------------------------------------------------------------===//
487b8ec3e35d2d7a56b21cb449d4a7bde8d9d12c2a5Hans Wennborg// Methods on ConversionSpecifier.
488b8ec3e35d2d7a56b21cb449d4a7bde8d9d12c2a5Hans Wennborg//===----------------------------------------------------------------------===//
489b8ec3e35d2d7a56b21cb449d4a7bde8d9d12c2a5Hans Wennborg
490b8ec3e35d2d7a56b21cb449d4a7bde8d9d12c2a5Hans Wennborgconst char *ConversionSpecifier::toString() const {
491b8ec3e35d2d7a56b21cb449d4a7bde8d9d12c2a5Hans Wennborg  switch (kind) {
492b8ec3e35d2d7a56b21cb449d4a7bde8d9d12c2a5Hans Wennborg  case dArg: return "d";
493275b6f52c7bcafc1f3cf291813b5c60ee776965aJordan Rose  case DArg: return "D";
494b8ec3e35d2d7a56b21cb449d4a7bde8d9d12c2a5Hans Wennborg  case iArg: return "i";
495b8ec3e35d2d7a56b21cb449d4a7bde8d9d12c2a5Hans Wennborg  case oArg: return "o";
496275b6f52c7bcafc1f3cf291813b5c60ee776965aJordan Rose  case OArg: return "O";
497b8ec3e35d2d7a56b21cb449d4a7bde8d9d12c2a5Hans Wennborg  case uArg: return "u";
498275b6f52c7bcafc1f3cf291813b5c60ee776965aJordan Rose  case UArg: return "U";
499b8ec3e35d2d7a56b21cb449d4a7bde8d9d12c2a5Hans Wennborg  case xArg: return "x";
500b8ec3e35d2d7a56b21cb449d4a7bde8d9d12c2a5Hans Wennborg  case XArg: return "X";
501b8ec3e35d2d7a56b21cb449d4a7bde8d9d12c2a5Hans Wennborg  case fArg: return "f";
502b8ec3e35d2d7a56b21cb449d4a7bde8d9d12c2a5Hans Wennborg  case FArg: return "F";
503b8ec3e35d2d7a56b21cb449d4a7bde8d9d12c2a5Hans Wennborg  case eArg: return "e";
504b8ec3e35d2d7a56b21cb449d4a7bde8d9d12c2a5Hans Wennborg  case EArg: return "E";
505b8ec3e35d2d7a56b21cb449d4a7bde8d9d12c2a5Hans Wennborg  case gArg: return "g";
506b8ec3e35d2d7a56b21cb449d4a7bde8d9d12c2a5Hans Wennborg  case GArg: return "G";
507b8ec3e35d2d7a56b21cb449d4a7bde8d9d12c2a5Hans Wennborg  case aArg: return "a";
508b8ec3e35d2d7a56b21cb449d4a7bde8d9d12c2a5Hans Wennborg  case AArg: return "A";
509b8ec3e35d2d7a56b21cb449d4a7bde8d9d12c2a5Hans Wennborg  case cArg: return "c";
510b8ec3e35d2d7a56b21cb449d4a7bde8d9d12c2a5Hans Wennborg  case sArg: return "s";
511b8ec3e35d2d7a56b21cb449d4a7bde8d9d12c2a5Hans Wennborg  case pArg: return "p";
512b8ec3e35d2d7a56b21cb449d4a7bde8d9d12c2a5Hans Wennborg  case nArg: return "n";
513b8ec3e35d2d7a56b21cb449d4a7bde8d9d12c2a5Hans Wennborg  case PercentArg:  return "%";
514b8ec3e35d2d7a56b21cb449d4a7bde8d9d12c2a5Hans Wennborg  case ScanListArg: return "[";
515b8ec3e35d2d7a56b21cb449d4a7bde8d9d12c2a5Hans Wennborg  case InvalidSpecifier: return NULL;
516b8ec3e35d2d7a56b21cb449d4a7bde8d9d12c2a5Hans Wennborg
517b8ec3e35d2d7a56b21cb449d4a7bde8d9d12c2a5Hans Wennborg  // MacOS X unicode extensions.
518b8ec3e35d2d7a56b21cb449d4a7bde8d9d12c2a5Hans Wennborg  case CArg: return "C";
519b8ec3e35d2d7a56b21cb449d4a7bde8d9d12c2a5Hans Wennborg  case SArg: return "S";
520b8ec3e35d2d7a56b21cb449d4a7bde8d9d12c2a5Hans Wennborg
521b8ec3e35d2d7a56b21cb449d4a7bde8d9d12c2a5Hans Wennborg  // Objective-C specific specifiers.
522b8ec3e35d2d7a56b21cb449d4a7bde8d9d12c2a5Hans Wennborg  case ObjCObjArg: return "@";
523b8ec3e35d2d7a56b21cb449d4a7bde8d9d12c2a5Hans Wennborg
524b8ec3e35d2d7a56b21cb449d4a7bde8d9d12c2a5Hans Wennborg  // GlibC specific specifiers.
525b8ec3e35d2d7a56b21cb449d4a7bde8d9d12c2a5Hans Wennborg  case PrintErrno: return "m";
526b8ec3e35d2d7a56b21cb449d4a7bde8d9d12c2a5Hans Wennborg  }
527b8ec3e35d2d7a56b21cb449d4a7bde8d9d12c2a5Hans Wennborg  return NULL;
528b8ec3e35d2d7a56b21cb449d4a7bde8d9d12c2a5Hans Wennborg}
529b8ec3e35d2d7a56b21cb449d4a7bde8d9d12c2a5Hans Wennborg
530dc84cd5efdd3430efb22546b4ac656aa0540b210David BlaikieOptional<ConversionSpecifier>
531670941c28c0683ecc251dafdf093a71629625dc9Jordan RoseConversionSpecifier::getStandardSpecifier() const {
532670941c28c0683ecc251dafdf093a71629625dc9Jordan Rose  ConversionSpecifier::Kind NewKind;
533670941c28c0683ecc251dafdf093a71629625dc9Jordan Rose
534670941c28c0683ecc251dafdf093a71629625dc9Jordan Rose  switch (getKind()) {
535670941c28c0683ecc251dafdf093a71629625dc9Jordan Rose  default:
53666874fb18afbffb8b2ca05576851a64534be3352David Blaikie    return None;
537670941c28c0683ecc251dafdf093a71629625dc9Jordan Rose  case DArg:
538670941c28c0683ecc251dafdf093a71629625dc9Jordan Rose    NewKind = dArg;
539670941c28c0683ecc251dafdf093a71629625dc9Jordan Rose    break;
540670941c28c0683ecc251dafdf093a71629625dc9Jordan Rose  case UArg:
541670941c28c0683ecc251dafdf093a71629625dc9Jordan Rose    NewKind = uArg;
542670941c28c0683ecc251dafdf093a71629625dc9Jordan Rose    break;
543670941c28c0683ecc251dafdf093a71629625dc9Jordan Rose  case OArg:
544670941c28c0683ecc251dafdf093a71629625dc9Jordan Rose    NewKind = oArg;
545670941c28c0683ecc251dafdf093a71629625dc9Jordan Rose    break;
546670941c28c0683ecc251dafdf093a71629625dc9Jordan Rose  }
547670941c28c0683ecc251dafdf093a71629625dc9Jordan Rose
548670941c28c0683ecc251dafdf093a71629625dc9Jordan Rose  ConversionSpecifier FixedCS(*this);
549670941c28c0683ecc251dafdf093a71629625dc9Jordan Rose  FixedCS.setKind(NewKind);
550670941c28c0683ecc251dafdf093a71629625dc9Jordan Rose  return FixedCS;
551670941c28c0683ecc251dafdf093a71629625dc9Jordan Rose}
552670941c28c0683ecc251dafdf093a71629625dc9Jordan Rose
553b8ec3e35d2d7a56b21cb449d4a7bde8d9d12c2a5Hans Wennborg//===----------------------------------------------------------------------===//
554826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek// Methods on OptionalAmount.
555826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek//===----------------------------------------------------------------------===//
556826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek
5575f9e272e632e951b1efe824cd16acb4d96077930Chris Lattnervoid OptionalAmount::toString(raw_ostream &os) const {
558826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek  switch (hs) {
559826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek  case Invalid:
560826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek  case NotSpecified:
561826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek    return;
562826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek  case Arg:
563826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek    if (UsesDotPrefix)
564826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek        os << ".";
565826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek    if (usesPositionalArg())
566826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek      os << "*" << getPositionalArgIndex() << "$";
567826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek    else
568826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek      os << "*";
569826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek    break;
570826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek  case Constant:
571826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek    if (UsesDotPrefix)
572826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek        os << ".";
573826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek    os << amt;
574826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek    break;
575826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek  }
576826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek}
577826a3457f737f1fc45a22954fd1bfde38160c165Ted Kremenek
578bbb6bb4952b77e57b842b4d3096848123ae690e7Jordan Rosebool FormatSpecifier::hasValidLengthModifier(const TargetInfo &Target) const {
579a412a499162c46211c10ad92045b9b5fd2298edeTed Kremenek  switch (LM.getKind()) {
580a412a499162c46211c10ad92045b9b5fd2298edeTed Kremenek    case LengthModifier::None:
581a412a499162c46211c10ad92045b9b5fd2298edeTed Kremenek      return true;
582a412a499162c46211c10ad92045b9b5fd2298edeTed Kremenek
58332addd519c6699000ff79c387a1c87f0ab7c3698Hans Wennborg    // Handle most integer flags
584a412a499162c46211c10ad92045b9b5fd2298edeTed Kremenek    case LengthModifier::AsChar:
585a412a499162c46211c10ad92045b9b5fd2298edeTed Kremenek    case LengthModifier::AsShort:
586a412a499162c46211c10ad92045b9b5fd2298edeTed Kremenek    case LengthModifier::AsLongLong:
58732addd519c6699000ff79c387a1c87f0ab7c3698Hans Wennborg    case LengthModifier::AsQuad:
588a412a499162c46211c10ad92045b9b5fd2298edeTed Kremenek    case LengthModifier::AsIntMax:
589a412a499162c46211c10ad92045b9b5fd2298edeTed Kremenek    case LengthModifier::AsSizeT:
590a412a499162c46211c10ad92045b9b5fd2298edeTed Kremenek    case LengthModifier::AsPtrDiff:
591a412a499162c46211c10ad92045b9b5fd2298edeTed Kremenek      switch (CS.getKind()) {
592a412a499162c46211c10ad92045b9b5fd2298edeTed Kremenek        case ConversionSpecifier::dArg:
593275b6f52c7bcafc1f3cf291813b5c60ee776965aJordan Rose        case ConversionSpecifier::DArg:
594a412a499162c46211c10ad92045b9b5fd2298edeTed Kremenek        case ConversionSpecifier::iArg:
595a412a499162c46211c10ad92045b9b5fd2298edeTed Kremenek        case ConversionSpecifier::oArg:
596275b6f52c7bcafc1f3cf291813b5c60ee776965aJordan Rose        case ConversionSpecifier::OArg:
597a412a499162c46211c10ad92045b9b5fd2298edeTed Kremenek        case ConversionSpecifier::uArg:
598275b6f52c7bcafc1f3cf291813b5c60ee776965aJordan Rose        case ConversionSpecifier::UArg:
599a412a499162c46211c10ad92045b9b5fd2298edeTed Kremenek        case ConversionSpecifier::xArg:
600a412a499162c46211c10ad92045b9b5fd2298edeTed Kremenek        case ConversionSpecifier::XArg:
601a412a499162c46211c10ad92045b9b5fd2298edeTed Kremenek        case ConversionSpecifier::nArg:
602a412a499162c46211c10ad92045b9b5fd2298edeTed Kremenek          return true;
603a412a499162c46211c10ad92045b9b5fd2298edeTed Kremenek        default:
604a412a499162c46211c10ad92045b9b5fd2298edeTed Kremenek          return false;
605a412a499162c46211c10ad92045b9b5fd2298edeTed Kremenek      }
606a412a499162c46211c10ad92045b9b5fd2298edeTed Kremenek
60732addd519c6699000ff79c387a1c87f0ab7c3698Hans Wennborg    // Handle 'l' flag
608a412a499162c46211c10ad92045b9b5fd2298edeTed Kremenek    case LengthModifier::AsLong:
609a412a499162c46211c10ad92045b9b5fd2298edeTed Kremenek      switch (CS.getKind()) {
610a412a499162c46211c10ad92045b9b5fd2298edeTed Kremenek        case ConversionSpecifier::dArg:
611275b6f52c7bcafc1f3cf291813b5c60ee776965aJordan Rose        case ConversionSpecifier::DArg:
612a412a499162c46211c10ad92045b9b5fd2298edeTed Kremenek        case ConversionSpecifier::iArg:
613a412a499162c46211c10ad92045b9b5fd2298edeTed Kremenek        case ConversionSpecifier::oArg:
614275b6f52c7bcafc1f3cf291813b5c60ee776965aJordan Rose        case ConversionSpecifier::OArg:
615a412a499162c46211c10ad92045b9b5fd2298edeTed Kremenek        case ConversionSpecifier::uArg:
616275b6f52c7bcafc1f3cf291813b5c60ee776965aJordan Rose        case ConversionSpecifier::UArg:
617a412a499162c46211c10ad92045b9b5fd2298edeTed Kremenek        case ConversionSpecifier::xArg:
618a412a499162c46211c10ad92045b9b5fd2298edeTed Kremenek        case ConversionSpecifier::XArg:
619a412a499162c46211c10ad92045b9b5fd2298edeTed Kremenek        case ConversionSpecifier::aArg:
620a412a499162c46211c10ad92045b9b5fd2298edeTed Kremenek        case ConversionSpecifier::AArg:
621a412a499162c46211c10ad92045b9b5fd2298edeTed Kremenek        case ConversionSpecifier::fArg:
622a412a499162c46211c10ad92045b9b5fd2298edeTed Kremenek        case ConversionSpecifier::FArg:
623a412a499162c46211c10ad92045b9b5fd2298edeTed Kremenek        case ConversionSpecifier::eArg:
624a412a499162c46211c10ad92045b9b5fd2298edeTed Kremenek        case ConversionSpecifier::EArg:
625a412a499162c46211c10ad92045b9b5fd2298edeTed Kremenek        case ConversionSpecifier::gArg:
626a412a499162c46211c10ad92045b9b5fd2298edeTed Kremenek        case ConversionSpecifier::GArg:
627a412a499162c46211c10ad92045b9b5fd2298edeTed Kremenek        case ConversionSpecifier::nArg:
628a412a499162c46211c10ad92045b9b5fd2298edeTed Kremenek        case ConversionSpecifier::cArg:
629a412a499162c46211c10ad92045b9b5fd2298edeTed Kremenek        case ConversionSpecifier::sArg:
630ef1440b6eca118d46291166ce3302f9bba8e639bTed Kremenek        case ConversionSpecifier::ScanListArg:
631a412a499162c46211c10ad92045b9b5fd2298edeTed Kremenek          return true;
632a412a499162c46211c10ad92045b9b5fd2298edeTed Kremenek        default:
633a412a499162c46211c10ad92045b9b5fd2298edeTed Kremenek          return false;
634a412a499162c46211c10ad92045b9b5fd2298edeTed Kremenek      }
635a412a499162c46211c10ad92045b9b5fd2298edeTed Kremenek
636a412a499162c46211c10ad92045b9b5fd2298edeTed Kremenek    case LengthModifier::AsLongDouble:
637a412a499162c46211c10ad92045b9b5fd2298edeTed Kremenek      switch (CS.getKind()) {
638a412a499162c46211c10ad92045b9b5fd2298edeTed Kremenek        case ConversionSpecifier::aArg:
639a412a499162c46211c10ad92045b9b5fd2298edeTed Kremenek        case ConversionSpecifier::AArg:
640a412a499162c46211c10ad92045b9b5fd2298edeTed Kremenek        case ConversionSpecifier::fArg:
641a412a499162c46211c10ad92045b9b5fd2298edeTed Kremenek        case ConversionSpecifier::FArg:
642a412a499162c46211c10ad92045b9b5fd2298edeTed Kremenek        case ConversionSpecifier::eArg:
643a412a499162c46211c10ad92045b9b5fd2298edeTed Kremenek        case ConversionSpecifier::EArg:
644a412a499162c46211c10ad92045b9b5fd2298edeTed Kremenek        case ConversionSpecifier::gArg:
645a412a499162c46211c10ad92045b9b5fd2298edeTed Kremenek        case ConversionSpecifier::GArg:
646a412a499162c46211c10ad92045b9b5fd2298edeTed Kremenek          return true;
647bbb6bb4952b77e57b842b4d3096848123ae690e7Jordan Rose        // GNU libc extension.
6489d24c2cbd9cf1b7c165ccb13221f2efb2f4b49b0Ted Kremenek        case ConversionSpecifier::dArg:
6499d24c2cbd9cf1b7c165ccb13221f2efb2f4b49b0Ted Kremenek        case ConversionSpecifier::iArg:
6509d24c2cbd9cf1b7c165ccb13221f2efb2f4b49b0Ted Kremenek        case ConversionSpecifier::oArg:
6519d24c2cbd9cf1b7c165ccb13221f2efb2f4b49b0Ted Kremenek        case ConversionSpecifier::uArg:
6529d24c2cbd9cf1b7c165ccb13221f2efb2f4b49b0Ted Kremenek        case ConversionSpecifier::xArg:
6539d24c2cbd9cf1b7c165ccb13221f2efb2f4b49b0Ted Kremenek        case ConversionSpecifier::XArg:
654bbb6bb4952b77e57b842b4d3096848123ae690e7Jordan Rose          return !Target.getTriple().isOSDarwin() &&
655bbb6bb4952b77e57b842b4d3096848123ae690e7Jordan Rose                 !Target.getTriple().isOSWindows();
656a412a499162c46211c10ad92045b9b5fd2298edeTed Kremenek        default:
657a412a499162c46211c10ad92045b9b5fd2298edeTed Kremenek          return false;
658a412a499162c46211c10ad92045b9b5fd2298edeTed Kremenek      }
659d02deebce5f1b283101e035a7f5d5bab0d2068ecHans Wennborg
660d02deebce5f1b283101e035a7f5d5bab0d2068ecHans Wennborg    case LengthModifier::AsAllocate:
661d02deebce5f1b283101e035a7f5d5bab0d2068ecHans Wennborg      switch (CS.getKind()) {
662d02deebce5f1b283101e035a7f5d5bab0d2068ecHans Wennborg        case ConversionSpecifier::sArg:
663d02deebce5f1b283101e035a7f5d5bab0d2068ecHans Wennborg        case ConversionSpecifier::SArg:
66428058d179ae40edc66135458849f1073c841bc74Hans Wennborg        case ConversionSpecifier::ScanListArg:
665d02deebce5f1b283101e035a7f5d5bab0d2068ecHans Wennborg          return true;
666d02deebce5f1b283101e035a7f5d5bab0d2068ecHans Wennborg        default:
667d02deebce5f1b283101e035a7f5d5bab0d2068ecHans Wennborg          return false;
668d02deebce5f1b283101e035a7f5d5bab0d2068ecHans Wennborg      }
66937969b7e14d6a4dfd934ef6d3738cc90b832ec1dHans Wennborg
67037969b7e14d6a4dfd934ef6d3738cc90b832ec1dHans Wennborg    case LengthModifier::AsMAllocate:
67137969b7e14d6a4dfd934ef6d3738cc90b832ec1dHans Wennborg      switch (CS.getKind()) {
67237969b7e14d6a4dfd934ef6d3738cc90b832ec1dHans Wennborg        case ConversionSpecifier::cArg:
67337969b7e14d6a4dfd934ef6d3738cc90b832ec1dHans Wennborg        case ConversionSpecifier::CArg:
67437969b7e14d6a4dfd934ef6d3738cc90b832ec1dHans Wennborg        case ConversionSpecifier::sArg:
67537969b7e14d6a4dfd934ef6d3738cc90b832ec1dHans Wennborg        case ConversionSpecifier::SArg:
67637969b7e14d6a4dfd934ef6d3738cc90b832ec1dHans Wennborg        case ConversionSpecifier::ScanListArg:
67737969b7e14d6a4dfd934ef6d3738cc90b832ec1dHans Wennborg          return true;
67837969b7e14d6a4dfd934ef6d3738cc90b832ec1dHans Wennborg        default:
67937969b7e14d6a4dfd934ef6d3738cc90b832ec1dHans Wennborg          return false;
68037969b7e14d6a4dfd934ef6d3738cc90b832ec1dHans Wennborg      }
681a412a499162c46211c10ad92045b9b5fd2298edeTed Kremenek  }
6823026348bd4c13a0f83b59839f64065e0fcbea253David Blaikie  llvm_unreachable("Invalid LengthModifier Kind!");
683a412a499162c46211c10ad92045b9b5fd2298edeTed Kremenek}
68476517426dc8bf7734c07eefc35171a6bfdba1a2bHans Wennborg
68576517426dc8bf7734c07eefc35171a6bfdba1a2bHans Wennborgbool FormatSpecifier::hasStandardLengthModifier() const {
68676517426dc8bf7734c07eefc35171a6bfdba1a2bHans Wennborg  switch (LM.getKind()) {
68776517426dc8bf7734c07eefc35171a6bfdba1a2bHans Wennborg    case LengthModifier::None:
68876517426dc8bf7734c07eefc35171a6bfdba1a2bHans Wennborg    case LengthModifier::AsChar:
68976517426dc8bf7734c07eefc35171a6bfdba1a2bHans Wennborg    case LengthModifier::AsShort:
69076517426dc8bf7734c07eefc35171a6bfdba1a2bHans Wennborg    case LengthModifier::AsLong:
69176517426dc8bf7734c07eefc35171a6bfdba1a2bHans Wennborg    case LengthModifier::AsLongLong:
69276517426dc8bf7734c07eefc35171a6bfdba1a2bHans Wennborg    case LengthModifier::AsIntMax:
69376517426dc8bf7734c07eefc35171a6bfdba1a2bHans Wennborg    case LengthModifier::AsSizeT:
69476517426dc8bf7734c07eefc35171a6bfdba1a2bHans Wennborg    case LengthModifier::AsPtrDiff:
69576517426dc8bf7734c07eefc35171a6bfdba1a2bHans Wennborg    case LengthModifier::AsLongDouble:
69676517426dc8bf7734c07eefc35171a6bfdba1a2bHans Wennborg      return true;
69776517426dc8bf7734c07eefc35171a6bfdba1a2bHans Wennborg    case LengthModifier::AsAllocate:
69876517426dc8bf7734c07eefc35171a6bfdba1a2bHans Wennborg    case LengthModifier::AsMAllocate:
69976517426dc8bf7734c07eefc35171a6bfdba1a2bHans Wennborg    case LengthModifier::AsQuad:
70076517426dc8bf7734c07eefc35171a6bfdba1a2bHans Wennborg      return false;
70176517426dc8bf7734c07eefc35171a6bfdba1a2bHans Wennborg  }
70276517426dc8bf7734c07eefc35171a6bfdba1a2bHans Wennborg  llvm_unreachable("Invalid LengthModifier Kind!");
70376517426dc8bf7734c07eefc35171a6bfdba1a2bHans Wennborg}
70476517426dc8bf7734c07eefc35171a6bfdba1a2bHans Wennborg
70576517426dc8bf7734c07eefc35171a6bfdba1a2bHans Wennborgbool FormatSpecifier::hasStandardConversionSpecifier(const LangOptions &LangOpt) const {
70676517426dc8bf7734c07eefc35171a6bfdba1a2bHans Wennborg  switch (CS.getKind()) {
70776517426dc8bf7734c07eefc35171a6bfdba1a2bHans Wennborg    case ConversionSpecifier::cArg:
70876517426dc8bf7734c07eefc35171a6bfdba1a2bHans Wennborg    case ConversionSpecifier::dArg:
70976517426dc8bf7734c07eefc35171a6bfdba1a2bHans Wennborg    case ConversionSpecifier::iArg:
71076517426dc8bf7734c07eefc35171a6bfdba1a2bHans Wennborg    case ConversionSpecifier::oArg:
71176517426dc8bf7734c07eefc35171a6bfdba1a2bHans Wennborg    case ConversionSpecifier::uArg:
71276517426dc8bf7734c07eefc35171a6bfdba1a2bHans Wennborg    case ConversionSpecifier::xArg:
71376517426dc8bf7734c07eefc35171a6bfdba1a2bHans Wennborg    case ConversionSpecifier::XArg:
71476517426dc8bf7734c07eefc35171a6bfdba1a2bHans Wennborg    case ConversionSpecifier::fArg:
71576517426dc8bf7734c07eefc35171a6bfdba1a2bHans Wennborg    case ConversionSpecifier::FArg:
71676517426dc8bf7734c07eefc35171a6bfdba1a2bHans Wennborg    case ConversionSpecifier::eArg:
71776517426dc8bf7734c07eefc35171a6bfdba1a2bHans Wennborg    case ConversionSpecifier::EArg:
71876517426dc8bf7734c07eefc35171a6bfdba1a2bHans Wennborg    case ConversionSpecifier::gArg:
71976517426dc8bf7734c07eefc35171a6bfdba1a2bHans Wennborg    case ConversionSpecifier::GArg:
72076517426dc8bf7734c07eefc35171a6bfdba1a2bHans Wennborg    case ConversionSpecifier::aArg:
72176517426dc8bf7734c07eefc35171a6bfdba1a2bHans Wennborg    case ConversionSpecifier::AArg:
72276517426dc8bf7734c07eefc35171a6bfdba1a2bHans Wennborg    case ConversionSpecifier::sArg:
72376517426dc8bf7734c07eefc35171a6bfdba1a2bHans Wennborg    case ConversionSpecifier::pArg:
72476517426dc8bf7734c07eefc35171a6bfdba1a2bHans Wennborg    case ConversionSpecifier::nArg:
72576517426dc8bf7734c07eefc35171a6bfdba1a2bHans Wennborg    case ConversionSpecifier::ObjCObjArg:
72676517426dc8bf7734c07eefc35171a6bfdba1a2bHans Wennborg    case ConversionSpecifier::ScanListArg:
72776517426dc8bf7734c07eefc35171a6bfdba1a2bHans Wennborg    case ConversionSpecifier::PercentArg:
72876517426dc8bf7734c07eefc35171a6bfdba1a2bHans Wennborg      return true;
72976517426dc8bf7734c07eefc35171a6bfdba1a2bHans Wennborg    case ConversionSpecifier::CArg:
73076517426dc8bf7734c07eefc35171a6bfdba1a2bHans Wennborg    case ConversionSpecifier::SArg:
73176517426dc8bf7734c07eefc35171a6bfdba1a2bHans Wennborg      return LangOpt.ObjC1 || LangOpt.ObjC2;
73276517426dc8bf7734c07eefc35171a6bfdba1a2bHans Wennborg    case ConversionSpecifier::InvalidSpecifier:
73376517426dc8bf7734c07eefc35171a6bfdba1a2bHans Wennborg    case ConversionSpecifier::PrintErrno:
734275b6f52c7bcafc1f3cf291813b5c60ee776965aJordan Rose    case ConversionSpecifier::DArg:
735275b6f52c7bcafc1f3cf291813b5c60ee776965aJordan Rose    case ConversionSpecifier::OArg:
736275b6f52c7bcafc1f3cf291813b5c60ee776965aJordan Rose    case ConversionSpecifier::UArg:
73776517426dc8bf7734c07eefc35171a6bfdba1a2bHans Wennborg      return false;
73876517426dc8bf7734c07eefc35171a6bfdba1a2bHans Wennborg  }
73976517426dc8bf7734c07eefc35171a6bfdba1a2bHans Wennborg  llvm_unreachable("Invalid ConversionSpecifier Kind!");
74076517426dc8bf7734c07eefc35171a6bfdba1a2bHans Wennborg}
74176517426dc8bf7734c07eefc35171a6bfdba1a2bHans Wennborg
74276517426dc8bf7734c07eefc35171a6bfdba1a2bHans Wennborgbool FormatSpecifier::hasStandardLengthConversionCombination() const {
74376517426dc8bf7734c07eefc35171a6bfdba1a2bHans Wennborg  if (LM.getKind() == LengthModifier::AsLongDouble) {
74476517426dc8bf7734c07eefc35171a6bfdba1a2bHans Wennborg    switch(CS.getKind()) {
74576517426dc8bf7734c07eefc35171a6bfdba1a2bHans Wennborg        case ConversionSpecifier::dArg:
74676517426dc8bf7734c07eefc35171a6bfdba1a2bHans Wennborg        case ConversionSpecifier::iArg:
74776517426dc8bf7734c07eefc35171a6bfdba1a2bHans Wennborg        case ConversionSpecifier::oArg:
74876517426dc8bf7734c07eefc35171a6bfdba1a2bHans Wennborg        case ConversionSpecifier::uArg:
74976517426dc8bf7734c07eefc35171a6bfdba1a2bHans Wennborg        case ConversionSpecifier::xArg:
75076517426dc8bf7734c07eefc35171a6bfdba1a2bHans Wennborg        case ConversionSpecifier::XArg:
75176517426dc8bf7734c07eefc35171a6bfdba1a2bHans Wennborg          return false;
75276517426dc8bf7734c07eefc35171a6bfdba1a2bHans Wennborg        default:
75376517426dc8bf7734c07eefc35171a6bfdba1a2bHans Wennborg          return true;
75476517426dc8bf7734c07eefc35171a6bfdba1a2bHans Wennborg    }
75576517426dc8bf7734c07eefc35171a6bfdba1a2bHans Wennborg  }
75676517426dc8bf7734c07eefc35171a6bfdba1a2bHans Wennborg  return true;
75776517426dc8bf7734c07eefc35171a6bfdba1a2bHans Wennborg}
7584684778993c667246039b4664acbce59dc99440cHans Wennborg
759dc84cd5efdd3430efb22546b4ac656aa0540b210David BlaikieOptional<LengthModifier> FormatSpecifier::getCorrectedLengthModifier() const {
7608be066e6733364cd34f25c4f7b7344f72aa23369Jordan Rose  if (CS.isAnyIntArg() || CS.getKind() == ConversionSpecifier::nArg) {
7618be066e6733364cd34f25c4f7b7344f72aa23369Jordan Rose    if (LM.getKind() == LengthModifier::AsLongDouble ||
7628be066e6733364cd34f25c4f7b7344f72aa23369Jordan Rose        LM.getKind() == LengthModifier::AsQuad) {
763bbb6bb4952b77e57b842b4d3096848123ae690e7Jordan Rose      LengthModifier FixedLM(LM);
764bbb6bb4952b77e57b842b4d3096848123ae690e7Jordan Rose      FixedLM.setKind(LengthModifier::AsLongLong);
765bbb6bb4952b77e57b842b4d3096848123ae690e7Jordan Rose      return FixedLM;
766bbb6bb4952b77e57b842b4d3096848123ae690e7Jordan Rose    }
767bbb6bb4952b77e57b842b4d3096848123ae690e7Jordan Rose  }
768bbb6bb4952b77e57b842b4d3096848123ae690e7Jordan Rose
76966874fb18afbffb8b2ca05576851a64534be3352David Blaikie  return None;
770bbb6bb4952b77e57b842b4d3096848123ae690e7Jordan Rose}
771bbb6bb4952b77e57b842b4d3096848123ae690e7Jordan Rose
7724684778993c667246039b4664acbce59dc99440cHans Wennborgbool FormatSpecifier::namedTypeToLengthModifier(QualType QT,
7734684778993c667246039b4664acbce59dc99440cHans Wennborg                                                LengthModifier &LM) {
7744684778993c667246039b4664acbce59dc99440cHans Wennborg  assert(isa<TypedefType>(QT) && "Expected a TypedefType");
7754684778993c667246039b4664acbce59dc99440cHans Wennborg  const TypedefNameDecl *Typedef = cast<TypedefType>(QT)->getDecl();
7764684778993c667246039b4664acbce59dc99440cHans Wennborg
7774684778993c667246039b4664acbce59dc99440cHans Wennborg  for (;;) {
7784684778993c667246039b4664acbce59dc99440cHans Wennborg    const IdentifierInfo *Identifier = Typedef->getIdentifier();
7794684778993c667246039b4664acbce59dc99440cHans Wennborg    if (Identifier->getName() == "size_t") {
7804684778993c667246039b4664acbce59dc99440cHans Wennborg      LM.setKind(LengthModifier::AsSizeT);
7814684778993c667246039b4664acbce59dc99440cHans Wennborg      return true;
7824684778993c667246039b4664acbce59dc99440cHans Wennborg    } else if (Identifier->getName() == "ssize_t") {
7834684778993c667246039b4664acbce59dc99440cHans Wennborg      // Not C99, but common in Unix.
7844684778993c667246039b4664acbce59dc99440cHans Wennborg      LM.setKind(LengthModifier::AsSizeT);
7854684778993c667246039b4664acbce59dc99440cHans Wennborg      return true;
7864684778993c667246039b4664acbce59dc99440cHans Wennborg    } else if (Identifier->getName() == "intmax_t") {
7874684778993c667246039b4664acbce59dc99440cHans Wennborg      LM.setKind(LengthModifier::AsIntMax);
7884684778993c667246039b4664acbce59dc99440cHans Wennborg      return true;
7894684778993c667246039b4664acbce59dc99440cHans Wennborg    } else if (Identifier->getName() == "uintmax_t") {
7904684778993c667246039b4664acbce59dc99440cHans Wennborg      LM.setKind(LengthModifier::AsIntMax);
7914684778993c667246039b4664acbce59dc99440cHans Wennborg      return true;
7924684778993c667246039b4664acbce59dc99440cHans Wennborg    } else if (Identifier->getName() == "ptrdiff_t") {
7934684778993c667246039b4664acbce59dc99440cHans Wennborg      LM.setKind(LengthModifier::AsPtrDiff);
7944684778993c667246039b4664acbce59dc99440cHans Wennborg      return true;
7954684778993c667246039b4664acbce59dc99440cHans Wennborg    }
7964684778993c667246039b4664acbce59dc99440cHans Wennborg
7974684778993c667246039b4664acbce59dc99440cHans Wennborg    QualType T = Typedef->getUnderlyingType();
7984684778993c667246039b4664acbce59dc99440cHans Wennborg    if (!isa<TypedefType>(T))
7994684778993c667246039b4664acbce59dc99440cHans Wennborg      break;
8004684778993c667246039b4664acbce59dc99440cHans Wennborg
8014684778993c667246039b4664acbce59dc99440cHans Wennborg    Typedef = cast<TypedefType>(T)->getDecl();
8024684778993c667246039b4664acbce59dc99440cHans Wennborg  }
8034684778993c667246039b4664acbce59dc99440cHans Wennborg  return false;
8044684778993c667246039b4664acbce59dc99440cHans Wennborg}
805