PrintfFormatString.cpp 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783
  1. //== PrintfFormatString.cpp - Analysis of printf format strings --*- C++ -*-==//
  2. //
  3. // The LLVM Compiler Infrastructure
  4. //
  5. // This file is distributed under the University of Illinois Open Source
  6. // License. See LICENSE.TXT for details.
  7. //
  8. //===----------------------------------------------------------------------===//
  9. //
  10. // Handling of format string in printf and friends. The structure of format
  11. // strings for fprintf() are described in C99 7.19.6.1.
  12. //
  13. //===----------------------------------------------------------------------===//
  14. #include "clang/Analysis/Analyses/FormatString.h"
  15. #include "FormatStringParsing.h"
  16. #include "clang/Basic/TargetInfo.h"
  17. using clang::analyze_format_string::ArgType;
  18. using clang::analyze_format_string::FormatStringHandler;
  19. using clang::analyze_format_string::LengthModifier;
  20. using clang::analyze_format_string::OptionalAmount;
  21. using clang::analyze_format_string::ConversionSpecifier;
  22. using clang::analyze_printf::PrintfSpecifier;
  23. using namespace clang;
  24. typedef clang::analyze_format_string::SpecifierResult<PrintfSpecifier>
  25. PrintfSpecifierResult;
  26. //===----------------------------------------------------------------------===//
  27. // Methods for parsing format strings.
  28. //===----------------------------------------------------------------------===//
  29. using analyze_format_string::ParseNonPositionAmount;
  30. static bool ParsePrecision(FormatStringHandler &H, PrintfSpecifier &FS,
  31. const char *Start, const char *&Beg, const char *E,
  32. unsigned *argIndex) {
  33. if (argIndex) {
  34. FS.setPrecision(ParseNonPositionAmount(Beg, E, *argIndex));
  35. } else {
  36. const OptionalAmount Amt = ParsePositionAmount(H, Start, Beg, E,
  37. analyze_format_string::PrecisionPos);
  38. if (Amt.isInvalid())
  39. return true;
  40. FS.setPrecision(Amt);
  41. }
  42. return false;
  43. }
  44. static PrintfSpecifierResult ParsePrintfSpecifier(FormatStringHandler &H,
  45. const char *&Beg,
  46. const char *E,
  47. unsigned &argIndex,
  48. const LangOptions &LO,
  49. const TargetInfo &Target) {
  50. using namespace clang::analyze_format_string;
  51. using namespace clang::analyze_printf;
  52. const char *I = Beg;
  53. const char *Start = 0;
  54. UpdateOnReturn <const char*> UpdateBeg(Beg, I);
  55. // Look for a '%' character that indicates the start of a format specifier.
  56. for ( ; I != E ; ++I) {
  57. char c = *I;
  58. if (c == '\0') {
  59. // Detect spurious null characters, which are likely errors.
  60. H.HandleNullChar(I);
  61. return true;
  62. }
  63. if (c == '%') {
  64. Start = I++; // Record the start of the format specifier.
  65. break;
  66. }
  67. }
  68. // No format specifier found?
  69. if (!Start)
  70. return false;
  71. if (I == E) {
  72. // No more characters left?
  73. H.HandleIncompleteSpecifier(Start, E - Start);
  74. return true;
  75. }
  76. PrintfSpecifier FS;
  77. if (ParseArgPosition(H, FS, Start, I, E))
  78. return true;
  79. if (I == E) {
  80. // No more characters left?
  81. H.HandleIncompleteSpecifier(Start, E - Start);
  82. return true;
  83. }
  84. // Look for flags (if any).
  85. bool hasMore = true;
  86. for ( ; I != E; ++I) {
  87. switch (*I) {
  88. default: hasMore = false; break;
  89. case '\'':
  90. // FIXME: POSIX specific. Always accept?
  91. FS.setHasThousandsGrouping(I);
  92. break;
  93. case '-': FS.setIsLeftJustified(I); break;
  94. case '+': FS.setHasPlusPrefix(I); break;
  95. case ' ': FS.setHasSpacePrefix(I); break;
  96. case '#': FS.setHasAlternativeForm(I); break;
  97. case '0': FS.setHasLeadingZeros(I); break;
  98. }
  99. if (!hasMore)
  100. break;
  101. }
  102. if (I == E) {
  103. // No more characters left?
  104. H.HandleIncompleteSpecifier(Start, E - Start);
  105. return true;
  106. }
  107. // Look for the field width (if any).
  108. if (ParseFieldWidth(H, FS, Start, I, E,
  109. FS.usesPositionalArg() ? 0 : &argIndex))
  110. return true;
  111. if (I == E) {
  112. // No more characters left?
  113. H.HandleIncompleteSpecifier(Start, E - Start);
  114. return true;
  115. }
  116. // Look for the precision (if any).
  117. if (*I == '.') {
  118. ++I;
  119. if (I == E) {
  120. H.HandleIncompleteSpecifier(Start, E - Start);
  121. return true;
  122. }
  123. if (ParsePrecision(H, FS, Start, I, E,
  124. FS.usesPositionalArg() ? 0 : &argIndex))
  125. return true;
  126. if (I == E) {
  127. // No more characters left?
  128. H.HandleIncompleteSpecifier(Start, E - Start);
  129. return true;
  130. }
  131. }
  132. // Look for the length modifier.
  133. if (ParseLengthModifier(FS, I, E, LO) && I == E) {
  134. // No more characters left?
  135. H.HandleIncompleteSpecifier(Start, E - Start);
  136. return true;
  137. }
  138. if (*I == '\0') {
  139. // Detect spurious null characters, which are likely errors.
  140. H.HandleNullChar(I);
  141. return true;
  142. }
  143. // Finally, look for the conversion specifier.
  144. const char *conversionPosition = I++;
  145. ConversionSpecifier::Kind k = ConversionSpecifier::InvalidSpecifier;
  146. switch (*conversionPosition) {
  147. default:
  148. break;
  149. // C99: 7.19.6.1 (section 8).
  150. case '%': k = ConversionSpecifier::PercentArg; break;
  151. case 'A': k = ConversionSpecifier::AArg; break;
  152. case 'E': k = ConversionSpecifier::EArg; break;
  153. case 'F': k = ConversionSpecifier::FArg; break;
  154. case 'G': k = ConversionSpecifier::GArg; break;
  155. case 'X': k = ConversionSpecifier::XArg; break;
  156. case 'a': k = ConversionSpecifier::aArg; break;
  157. case 'c': k = ConversionSpecifier::cArg; break;
  158. case 'd': k = ConversionSpecifier::dArg; break;
  159. case 'e': k = ConversionSpecifier::eArg; break;
  160. case 'f': k = ConversionSpecifier::fArg; break;
  161. case 'g': k = ConversionSpecifier::gArg; break;
  162. case 'i': k = ConversionSpecifier::iArg; break;
  163. case 'n': k = ConversionSpecifier::nArg; break;
  164. case 'o': k = ConversionSpecifier::oArg; break;
  165. case 'p': k = ConversionSpecifier::pArg; break;
  166. case 's': k = ConversionSpecifier::sArg; break;
  167. case 'u': k = ConversionSpecifier::uArg; break;
  168. case 'x': k = ConversionSpecifier::xArg; break;
  169. // POSIX specific.
  170. case 'C': k = ConversionSpecifier::CArg; break;
  171. case 'S': k = ConversionSpecifier::SArg; break;
  172. // Objective-C.
  173. case '@': k = ConversionSpecifier::ObjCObjArg; break;
  174. // Glibc specific.
  175. case 'm': k = ConversionSpecifier::PrintErrno; break;
  176. // Apple-specific
  177. case 'D':
  178. if (Target.getTriple().isOSDarwin())
  179. k = ConversionSpecifier::DArg;
  180. break;
  181. case 'O':
  182. if (Target.getTriple().isOSDarwin())
  183. k = ConversionSpecifier::OArg;
  184. break;
  185. case 'U':
  186. if (Target.getTriple().isOSDarwin())
  187. k = ConversionSpecifier::UArg;
  188. break;
  189. }
  190. PrintfConversionSpecifier CS(conversionPosition, k);
  191. FS.setConversionSpecifier(CS);
  192. if (CS.consumesDataArgument() && !FS.usesPositionalArg())
  193. FS.setArgIndex(argIndex++);
  194. if (k == ConversionSpecifier::InvalidSpecifier) {
  195. // Assume the conversion takes one argument.
  196. return !H.HandleInvalidPrintfConversionSpecifier(FS, Start, I - Start);
  197. }
  198. return PrintfSpecifierResult(Start, FS);
  199. }
  200. bool clang::analyze_format_string::ParsePrintfString(FormatStringHandler &H,
  201. const char *I,
  202. const char *E,
  203. const LangOptions &LO,
  204. const TargetInfo &Target) {
  205. unsigned argIndex = 0;
  206. // Keep looking for a format specifier until we have exhausted the string.
  207. while (I != E) {
  208. const PrintfSpecifierResult &FSR = ParsePrintfSpecifier(H, I, E, argIndex,
  209. LO, Target);
  210. // Did a fail-stop error of any kind occur when parsing the specifier?
  211. // If so, don't do any more processing.
  212. if (FSR.shouldStop())
  213. return true;
  214. // Did we exhaust the string or encounter an error that
  215. // we can recover from?
  216. if (!FSR.hasValue())
  217. continue;
  218. // We have a format specifier. Pass it to the callback.
  219. if (!H.HandlePrintfSpecifier(FSR.getValue(), FSR.getStart(),
  220. I - FSR.getStart()))
  221. return true;
  222. }
  223. assert(I == E && "Format string not exhausted");
  224. return false;
  225. }
  226. //===----------------------------------------------------------------------===//
  227. // Methods on PrintfSpecifier.
  228. //===----------------------------------------------------------------------===//
  229. ArgType PrintfSpecifier::getArgType(ASTContext &Ctx,
  230. bool IsObjCLiteral) const {
  231. const PrintfConversionSpecifier &CS = getConversionSpecifier();
  232. if (!CS.consumesDataArgument())
  233. return ArgType::Invalid();
  234. if (CS.getKind() == ConversionSpecifier::cArg)
  235. switch (LM.getKind()) {
  236. case LengthModifier::None: return Ctx.IntTy;
  237. case LengthModifier::AsLong:
  238. return ArgType(ArgType::WIntTy, "wint_t");
  239. default:
  240. return ArgType::Invalid();
  241. }
  242. if (CS.isIntArg())
  243. switch (LM.getKind()) {
  244. case LengthModifier::AsLongDouble:
  245. // GNU extension.
  246. return Ctx.LongLongTy;
  247. case LengthModifier::None:
  248. return Ctx.IntTy;
  249. case LengthModifier::AsInt32:
  250. return ArgType(Ctx.IntTy, "__int32");
  251. case LengthModifier::AsChar: return ArgType::AnyCharTy;
  252. case LengthModifier::AsShort: return Ctx.ShortTy;
  253. case LengthModifier::AsLong: return Ctx.LongTy;
  254. case LengthModifier::AsLongLong:
  255. case LengthModifier::AsQuad:
  256. return Ctx.LongLongTy;
  257. case LengthModifier::AsInt64:
  258. return ArgType(Ctx.LongLongTy, "__int64");
  259. case LengthModifier::AsIntMax:
  260. return ArgType(Ctx.getIntMaxType(), "intmax_t");
  261. case LengthModifier::AsSizeT:
  262. // FIXME: How to get the corresponding signed version of size_t?
  263. return ArgType();
  264. case LengthModifier::AsInt3264:
  265. return Ctx.getTargetInfo().getTriple().isArch64Bit()
  266. ? ArgType(Ctx.LongLongTy, "__int64")
  267. : ArgType(Ctx.IntTy, "__int32");
  268. case LengthModifier::AsPtrDiff:
  269. return ArgType(Ctx.getPointerDiffType(), "ptrdiff_t");
  270. case LengthModifier::AsAllocate:
  271. case LengthModifier::AsMAllocate:
  272. return ArgType::Invalid();
  273. }
  274. if (CS.isUIntArg())
  275. switch (LM.getKind()) {
  276. case LengthModifier::AsLongDouble:
  277. // GNU extension.
  278. return Ctx.UnsignedLongLongTy;
  279. case LengthModifier::None:
  280. return Ctx.UnsignedIntTy;
  281. case LengthModifier::AsInt32:
  282. return ArgType(Ctx.UnsignedIntTy, "unsigned __int32");
  283. case LengthModifier::AsChar: return Ctx.UnsignedCharTy;
  284. case LengthModifier::AsShort: return Ctx.UnsignedShortTy;
  285. case LengthModifier::AsLong: return Ctx.UnsignedLongTy;
  286. case LengthModifier::AsLongLong:
  287. case LengthModifier::AsQuad:
  288. return Ctx.UnsignedLongLongTy;
  289. case LengthModifier::AsInt64:
  290. return ArgType(Ctx.UnsignedLongLongTy, "unsigned __int64");
  291. case LengthModifier::AsIntMax:
  292. return ArgType(Ctx.getUIntMaxType(), "uintmax_t");
  293. case LengthModifier::AsSizeT:
  294. return ArgType(Ctx.getSizeType(), "size_t");
  295. case LengthModifier::AsInt3264:
  296. return Ctx.getTargetInfo().getTriple().isArch64Bit()
  297. ? ArgType(Ctx.UnsignedLongLongTy, "unsigned __int64")
  298. : ArgType(Ctx.UnsignedIntTy, "unsigned __int32");
  299. case LengthModifier::AsPtrDiff:
  300. // FIXME: How to get the corresponding unsigned
  301. // version of ptrdiff_t?
  302. return ArgType();
  303. case LengthModifier::AsAllocate:
  304. case LengthModifier::AsMAllocate:
  305. return ArgType::Invalid();
  306. }
  307. if (CS.isDoubleArg()) {
  308. if (LM.getKind() == LengthModifier::AsLongDouble)
  309. return Ctx.LongDoubleTy;
  310. return Ctx.DoubleTy;
  311. }
  312. if (CS.getKind() == ConversionSpecifier::nArg) {
  313. switch (LM.getKind()) {
  314. case LengthModifier::None:
  315. return ArgType::PtrTo(Ctx.IntTy);
  316. case LengthModifier::AsChar:
  317. return ArgType::PtrTo(Ctx.SignedCharTy);
  318. case LengthModifier::AsShort:
  319. return ArgType::PtrTo(Ctx.ShortTy);
  320. case LengthModifier::AsLong:
  321. return ArgType::PtrTo(Ctx.LongTy);
  322. case LengthModifier::AsLongLong:
  323. case LengthModifier::AsQuad:
  324. return ArgType::PtrTo(Ctx.LongLongTy);
  325. case LengthModifier::AsIntMax:
  326. return ArgType::PtrTo(ArgType(Ctx.getIntMaxType(), "intmax_t"));
  327. case LengthModifier::AsSizeT:
  328. return ArgType(); // FIXME: ssize_t
  329. case LengthModifier::AsPtrDiff:
  330. return ArgType::PtrTo(ArgType(Ctx.getPointerDiffType(), "ptrdiff_t"));
  331. case LengthModifier::AsLongDouble:
  332. return ArgType(); // FIXME: Is this a known extension?
  333. case LengthModifier::AsAllocate:
  334. case LengthModifier::AsMAllocate:
  335. case LengthModifier::AsInt32:
  336. case LengthModifier::AsInt3264:
  337. case LengthModifier::AsInt64:
  338. return ArgType::Invalid();
  339. }
  340. }
  341. switch (CS.getKind()) {
  342. case ConversionSpecifier::sArg:
  343. if (LM.getKind() == LengthModifier::AsWideChar) {
  344. if (IsObjCLiteral)
  345. return ArgType(Ctx.getPointerType(Ctx.UnsignedShortTy.withConst()),
  346. "const unichar *");
  347. return ArgType(ArgType::WCStrTy, "wchar_t *");
  348. }
  349. return ArgType::CStrTy;
  350. case ConversionSpecifier::SArg:
  351. if (IsObjCLiteral)
  352. return ArgType(Ctx.getPointerType(Ctx.UnsignedShortTy.withConst()),
  353. "const unichar *");
  354. return ArgType(ArgType::WCStrTy, "wchar_t *");
  355. case ConversionSpecifier::CArg:
  356. if (IsObjCLiteral)
  357. return ArgType(Ctx.UnsignedShortTy, "unichar");
  358. return ArgType(Ctx.WideCharTy, "wchar_t");
  359. case ConversionSpecifier::pArg:
  360. return ArgType::CPointerTy;
  361. case ConversionSpecifier::ObjCObjArg:
  362. return ArgType::ObjCPointerTy;
  363. default:
  364. break;
  365. }
  366. // FIXME: Handle other cases.
  367. return ArgType();
  368. }
  369. bool PrintfSpecifier::fixType(QualType QT, const LangOptions &LangOpt,
  370. ASTContext &Ctx, bool IsObjCLiteral) {
  371. // %n is different from other conversion specifiers; don't try to fix it.
  372. if (CS.getKind() == ConversionSpecifier::nArg)
  373. return false;
  374. // Handle Objective-C objects first. Note that while the '%@' specifier will
  375. // not warn for structure pointer or void pointer arguments (because that's
  376. // how CoreFoundation objects are implemented), we only show a fixit for '%@'
  377. // if we know it's an object (block, id, class, or __attribute__((NSObject))).
  378. if (QT->isObjCRetainableType()) {
  379. if (!IsObjCLiteral)
  380. return false;
  381. CS.setKind(ConversionSpecifier::ObjCObjArg);
  382. // Disable irrelevant flags
  383. HasThousandsGrouping = false;
  384. HasPlusPrefix = false;
  385. HasSpacePrefix = false;
  386. HasAlternativeForm = false;
  387. HasLeadingZeroes = false;
  388. Precision.setHowSpecified(OptionalAmount::NotSpecified);
  389. LM.setKind(LengthModifier::None);
  390. return true;
  391. }
  392. // Handle strings next (char *, wchar_t *)
  393. if (QT->isPointerType() && (QT->getPointeeType()->isAnyCharacterType())) {
  394. CS.setKind(ConversionSpecifier::sArg);
  395. // Disable irrelevant flags
  396. HasAlternativeForm = 0;
  397. HasLeadingZeroes = 0;
  398. // Set the long length modifier for wide characters
  399. if (QT->getPointeeType()->isWideCharType())
  400. LM.setKind(LengthModifier::AsWideChar);
  401. else
  402. LM.setKind(LengthModifier::None);
  403. return true;
  404. }
  405. // If it's an enum, get its underlying type.
  406. if (const EnumType *ETy = QT->getAs<EnumType>())
  407. QT = ETy->getDecl()->getIntegerType();
  408. // We can only work with builtin types.
  409. const BuiltinType *BT = QT->getAs<BuiltinType>();
  410. if (!BT)
  411. return false;
  412. // Set length modifier
  413. switch (BT->getKind()) {
  414. case BuiltinType::Bool:
  415. case BuiltinType::WChar_U:
  416. case BuiltinType::WChar_S:
  417. case BuiltinType::Char16:
  418. case BuiltinType::Char32:
  419. case BuiltinType::UInt128:
  420. case BuiltinType::Int128:
  421. case BuiltinType::Half:
  422. // Various types which are non-trivial to correct.
  423. return false;
  424. #define SIGNED_TYPE(Id, SingletonId)
  425. #define UNSIGNED_TYPE(Id, SingletonId)
  426. #define FLOATING_TYPE(Id, SingletonId)
  427. #define BUILTIN_TYPE(Id, SingletonId) \
  428. case BuiltinType::Id:
  429. #include "clang/AST/BuiltinTypes.def"
  430. // Misc other stuff which doesn't make sense here.
  431. return false;
  432. case BuiltinType::UInt:
  433. case BuiltinType::Int:
  434. case BuiltinType::Float:
  435. case BuiltinType::Double:
  436. LM.setKind(LengthModifier::None);
  437. break;
  438. case BuiltinType::Char_U:
  439. case BuiltinType::UChar:
  440. case BuiltinType::Char_S:
  441. case BuiltinType::SChar:
  442. LM.setKind(LengthModifier::AsChar);
  443. break;
  444. case BuiltinType::Short:
  445. case BuiltinType::UShort:
  446. LM.setKind(LengthModifier::AsShort);
  447. break;
  448. case BuiltinType::Long:
  449. case BuiltinType::ULong:
  450. LM.setKind(LengthModifier::AsLong);
  451. break;
  452. case BuiltinType::LongLong:
  453. case BuiltinType::ULongLong:
  454. LM.setKind(LengthModifier::AsLongLong);
  455. break;
  456. case BuiltinType::LongDouble:
  457. LM.setKind(LengthModifier::AsLongDouble);
  458. break;
  459. }
  460. // Handle size_t, ptrdiff_t, etc. that have dedicated length modifiers in C99.
  461. if (isa<TypedefType>(QT) && (LangOpt.C99 || LangOpt.CPlusPlus11))
  462. namedTypeToLengthModifier(QT, LM);
  463. // If fixing the length modifier was enough, we might be done.
  464. if (hasValidLengthModifier(Ctx.getTargetInfo())) {
  465. // If we're going to offer a fix anyway, make sure the sign matches.
  466. switch (CS.getKind()) {
  467. case ConversionSpecifier::uArg:
  468. case ConversionSpecifier::UArg:
  469. if (QT->isSignedIntegerType())
  470. CS.setKind(clang::analyze_format_string::ConversionSpecifier::dArg);
  471. break;
  472. case ConversionSpecifier::dArg:
  473. case ConversionSpecifier::DArg:
  474. case ConversionSpecifier::iArg:
  475. if (QT->isUnsignedIntegerType() && !HasPlusPrefix)
  476. CS.setKind(clang::analyze_format_string::ConversionSpecifier::uArg);
  477. break;
  478. default:
  479. // Other specifiers do not have signed/unsigned variants.
  480. break;
  481. }
  482. const analyze_printf::ArgType &ATR = getArgType(Ctx, IsObjCLiteral);
  483. if (ATR.isValid() && ATR.matchesType(Ctx, QT))
  484. return true;
  485. }
  486. // Set conversion specifier and disable any flags which do not apply to it.
  487. // Let typedefs to char fall through to int, as %c is silly for uint8_t.
  488. if (!isa<TypedefType>(QT) && QT->isCharType()) {
  489. CS.setKind(ConversionSpecifier::cArg);
  490. LM.setKind(LengthModifier::None);
  491. Precision.setHowSpecified(OptionalAmount::NotSpecified);
  492. HasAlternativeForm = 0;
  493. HasLeadingZeroes = 0;
  494. HasPlusPrefix = 0;
  495. }
  496. // Test for Floating type first as LongDouble can pass isUnsignedIntegerType
  497. else if (QT->isRealFloatingType()) {
  498. CS.setKind(ConversionSpecifier::fArg);
  499. }
  500. else if (QT->isSignedIntegerType()) {
  501. CS.setKind(ConversionSpecifier::dArg);
  502. HasAlternativeForm = 0;
  503. }
  504. else if (QT->isUnsignedIntegerType()) {
  505. CS.setKind(ConversionSpecifier::uArg);
  506. HasAlternativeForm = 0;
  507. HasPlusPrefix = 0;
  508. } else {
  509. llvm_unreachable("Unexpected type");
  510. }
  511. return true;
  512. }
  513. void PrintfSpecifier::toString(raw_ostream &os) const {
  514. // Whilst some features have no defined order, we are using the order
  515. // appearing in the C99 standard (ISO/IEC 9899:1999 (E) 7.19.6.1)
  516. os << "%";
  517. // Positional args
  518. if (usesPositionalArg()) {
  519. os << getPositionalArgIndex() << "$";
  520. }
  521. // Conversion flags
  522. if (IsLeftJustified) os << "-";
  523. if (HasPlusPrefix) os << "+";
  524. if (HasSpacePrefix) os << " ";
  525. if (HasAlternativeForm) os << "#";
  526. if (HasLeadingZeroes) os << "0";
  527. // Minimum field width
  528. FieldWidth.toString(os);
  529. // Precision
  530. Precision.toString(os);
  531. // Length modifier
  532. os << LM.toString();
  533. // Conversion specifier
  534. os << CS.toString();
  535. }
  536. bool PrintfSpecifier::hasValidPlusPrefix() const {
  537. if (!HasPlusPrefix)
  538. return true;
  539. // The plus prefix only makes sense for signed conversions
  540. switch (CS.getKind()) {
  541. case ConversionSpecifier::dArg:
  542. case ConversionSpecifier::DArg:
  543. case ConversionSpecifier::iArg:
  544. case ConversionSpecifier::fArg:
  545. case ConversionSpecifier::FArg:
  546. case ConversionSpecifier::eArg:
  547. case ConversionSpecifier::EArg:
  548. case ConversionSpecifier::gArg:
  549. case ConversionSpecifier::GArg:
  550. case ConversionSpecifier::aArg:
  551. case ConversionSpecifier::AArg:
  552. return true;
  553. default:
  554. return false;
  555. }
  556. }
  557. bool PrintfSpecifier::hasValidAlternativeForm() const {
  558. if (!HasAlternativeForm)
  559. return true;
  560. // Alternate form flag only valid with the oxXaAeEfFgG conversions
  561. switch (CS.getKind()) {
  562. case ConversionSpecifier::oArg:
  563. case ConversionSpecifier::OArg:
  564. case ConversionSpecifier::xArg:
  565. case ConversionSpecifier::XArg:
  566. case ConversionSpecifier::aArg:
  567. case ConversionSpecifier::AArg:
  568. case ConversionSpecifier::eArg:
  569. case ConversionSpecifier::EArg:
  570. case ConversionSpecifier::fArg:
  571. case ConversionSpecifier::FArg:
  572. case ConversionSpecifier::gArg:
  573. case ConversionSpecifier::GArg:
  574. return true;
  575. default:
  576. return false;
  577. }
  578. }
  579. bool PrintfSpecifier::hasValidLeadingZeros() const {
  580. if (!HasLeadingZeroes)
  581. return true;
  582. // Leading zeroes flag only valid with the diouxXaAeEfFgG conversions
  583. switch (CS.getKind()) {
  584. case ConversionSpecifier::dArg:
  585. case ConversionSpecifier::DArg:
  586. case ConversionSpecifier::iArg:
  587. case ConversionSpecifier::oArg:
  588. case ConversionSpecifier::OArg:
  589. case ConversionSpecifier::uArg:
  590. case ConversionSpecifier::UArg:
  591. case ConversionSpecifier::xArg:
  592. case ConversionSpecifier::XArg:
  593. case ConversionSpecifier::aArg:
  594. case ConversionSpecifier::AArg:
  595. case ConversionSpecifier::eArg:
  596. case ConversionSpecifier::EArg:
  597. case ConversionSpecifier::fArg:
  598. case ConversionSpecifier::FArg:
  599. case ConversionSpecifier::gArg:
  600. case ConversionSpecifier::GArg:
  601. return true;
  602. default:
  603. return false;
  604. }
  605. }
  606. bool PrintfSpecifier::hasValidSpacePrefix() const {
  607. if (!HasSpacePrefix)
  608. return true;
  609. // The space prefix only makes sense for signed conversions
  610. switch (CS.getKind()) {
  611. case ConversionSpecifier::dArg:
  612. case ConversionSpecifier::DArg:
  613. case ConversionSpecifier::iArg:
  614. case ConversionSpecifier::fArg:
  615. case ConversionSpecifier::FArg:
  616. case ConversionSpecifier::eArg:
  617. case ConversionSpecifier::EArg:
  618. case ConversionSpecifier::gArg:
  619. case ConversionSpecifier::GArg:
  620. case ConversionSpecifier::aArg:
  621. case ConversionSpecifier::AArg:
  622. return true;
  623. default:
  624. return false;
  625. }
  626. }
  627. bool PrintfSpecifier::hasValidLeftJustified() const {
  628. if (!IsLeftJustified)
  629. return true;
  630. // The left justified flag is valid for all conversions except n
  631. switch (CS.getKind()) {
  632. case ConversionSpecifier::nArg:
  633. return false;
  634. default:
  635. return true;
  636. }
  637. }
  638. bool PrintfSpecifier::hasValidThousandsGroupingPrefix() const {
  639. if (!HasThousandsGrouping)
  640. return true;
  641. switch (CS.getKind()) {
  642. case ConversionSpecifier::dArg:
  643. case ConversionSpecifier::DArg:
  644. case ConversionSpecifier::iArg:
  645. case ConversionSpecifier::uArg:
  646. case ConversionSpecifier::UArg:
  647. case ConversionSpecifier::fArg:
  648. case ConversionSpecifier::FArg:
  649. case ConversionSpecifier::gArg:
  650. case ConversionSpecifier::GArg:
  651. return true;
  652. default:
  653. return false;
  654. }
  655. }
  656. bool PrintfSpecifier::hasValidPrecision() const {
  657. if (Precision.getHowSpecified() == OptionalAmount::NotSpecified)
  658. return true;
  659. // Precision is only valid with the diouxXaAeEfFgGs conversions
  660. switch (CS.getKind()) {
  661. case ConversionSpecifier::dArg:
  662. case ConversionSpecifier::DArg:
  663. case ConversionSpecifier::iArg:
  664. case ConversionSpecifier::oArg:
  665. case ConversionSpecifier::OArg:
  666. case ConversionSpecifier::uArg:
  667. case ConversionSpecifier::UArg:
  668. case ConversionSpecifier::xArg:
  669. case ConversionSpecifier::XArg:
  670. case ConversionSpecifier::aArg:
  671. case ConversionSpecifier::AArg:
  672. case ConversionSpecifier::eArg:
  673. case ConversionSpecifier::EArg:
  674. case ConversionSpecifier::fArg:
  675. case ConversionSpecifier::FArg:
  676. case ConversionSpecifier::gArg:
  677. case ConversionSpecifier::GArg:
  678. case ConversionSpecifier::sArg:
  679. return true;
  680. default:
  681. return false;
  682. }
  683. }
  684. bool PrintfSpecifier::hasValidFieldWidth() const {
  685. if (FieldWidth.getHowSpecified() == OptionalAmount::NotSpecified)
  686. return true;
  687. // The field width is valid for all conversions except n
  688. switch (CS.getKind()) {
  689. case ConversionSpecifier::nArg:
  690. return false;
  691. default:
  692. return true;
  693. }
  694. }