FormatString.cpp 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724
  1. // FormatString.cpp - Common stuff for handling printf/scanf formats -*- 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. // Shared details for processing format strings of printf and scanf
  11. // (and friends).
  12. //
  13. //===----------------------------------------------------------------------===//
  14. #include "FormatStringParsing.h"
  15. #include "clang/Basic/LangOptions.h"
  16. using clang::analyze_format_string::ArgType;
  17. using clang::analyze_format_string::FormatStringHandler;
  18. using clang::analyze_format_string::FormatSpecifier;
  19. using clang::analyze_format_string::LengthModifier;
  20. using clang::analyze_format_string::OptionalAmount;
  21. using clang::analyze_format_string::PositionContext;
  22. using clang::analyze_format_string::ConversionSpecifier;
  23. using namespace clang;
  24. // Key function to FormatStringHandler.
  25. FormatStringHandler::~FormatStringHandler() {}
  26. //===----------------------------------------------------------------------===//
  27. // Functions for parsing format strings components in both printf and
  28. // scanf format strings.
  29. //===----------------------------------------------------------------------===//
  30. OptionalAmount
  31. clang::analyze_format_string::ParseAmount(const char *&Beg, const char *E) {
  32. const char *I = Beg;
  33. UpdateOnReturn <const char*> UpdateBeg(Beg, I);
  34. unsigned accumulator = 0;
  35. bool hasDigits = false;
  36. for ( ; I != E; ++I) {
  37. char c = *I;
  38. if (c >= '0' && c <= '9') {
  39. hasDigits = true;
  40. accumulator = (accumulator * 10) + (c - '0');
  41. continue;
  42. }
  43. if (hasDigits)
  44. return OptionalAmount(OptionalAmount::Constant, accumulator, Beg, I - Beg,
  45. false);
  46. break;
  47. }
  48. return OptionalAmount();
  49. }
  50. OptionalAmount
  51. clang::analyze_format_string::ParseNonPositionAmount(const char *&Beg,
  52. const char *E,
  53. unsigned &argIndex) {
  54. if (*Beg == '*') {
  55. ++Beg;
  56. return OptionalAmount(OptionalAmount::Arg, argIndex++, Beg, 0, false);
  57. }
  58. return ParseAmount(Beg, E);
  59. }
  60. OptionalAmount
  61. clang::analyze_format_string::ParsePositionAmount(FormatStringHandler &H,
  62. const char *Start,
  63. const char *&Beg,
  64. const char *E,
  65. PositionContext p) {
  66. if (*Beg == '*') {
  67. const char *I = Beg + 1;
  68. const OptionalAmount &Amt = ParseAmount(I, E);
  69. if (Amt.getHowSpecified() == OptionalAmount::NotSpecified) {
  70. H.HandleInvalidPosition(Beg, I - Beg, p);
  71. return OptionalAmount(false);
  72. }
  73. if (I == E) {
  74. // No more characters left?
  75. H.HandleIncompleteSpecifier(Start, E - Start);
  76. return OptionalAmount(false);
  77. }
  78. assert(Amt.getHowSpecified() == OptionalAmount::Constant);
  79. if (*I == '$') {
  80. // Handle positional arguments
  81. // Special case: '*0$', since this is an easy mistake.
  82. if (Amt.getConstantAmount() == 0) {
  83. H.HandleZeroPosition(Beg, I - Beg + 1);
  84. return OptionalAmount(false);
  85. }
  86. const char *Tmp = Beg;
  87. Beg = ++I;
  88. return OptionalAmount(OptionalAmount::Arg, Amt.getConstantAmount() - 1,
  89. Tmp, 0, true);
  90. }
  91. H.HandleInvalidPosition(Beg, I - Beg, p);
  92. return OptionalAmount(false);
  93. }
  94. return ParseAmount(Beg, E);
  95. }
  96. bool
  97. clang::analyze_format_string::ParseFieldWidth(FormatStringHandler &H,
  98. FormatSpecifier &CS,
  99. const char *Start,
  100. const char *&Beg, const char *E,
  101. unsigned *argIndex) {
  102. // FIXME: Support negative field widths.
  103. if (argIndex) {
  104. CS.setFieldWidth(ParseNonPositionAmount(Beg, E, *argIndex));
  105. }
  106. else {
  107. const OptionalAmount Amt =
  108. ParsePositionAmount(H, Start, Beg, E,
  109. analyze_format_string::FieldWidthPos);
  110. if (Amt.isInvalid())
  111. return true;
  112. CS.setFieldWidth(Amt);
  113. }
  114. return false;
  115. }
  116. bool
  117. clang::analyze_format_string::ParseArgPosition(FormatStringHandler &H,
  118. FormatSpecifier &FS,
  119. const char *Start,
  120. const char *&Beg,
  121. const char *E) {
  122. const char *I = Beg;
  123. const OptionalAmount &Amt = ParseAmount(I, E);
  124. if (I == E) {
  125. // No more characters left?
  126. H.HandleIncompleteSpecifier(Start, E - Start);
  127. return true;
  128. }
  129. if (Amt.getHowSpecified() == OptionalAmount::Constant && *(I++) == '$') {
  130. // Warn that positional arguments are non-standard.
  131. H.HandlePosition(Start, I - Start);
  132. // Special case: '%0$', since this is an easy mistake.
  133. if (Amt.getConstantAmount() == 0) {
  134. H.HandleZeroPosition(Start, I - Start);
  135. return true;
  136. }
  137. FS.setArgIndex(Amt.getConstantAmount() - 1);
  138. FS.setUsesPositionalArg();
  139. // Update the caller's pointer if we decided to consume
  140. // these characters.
  141. Beg = I;
  142. return false;
  143. }
  144. return false;
  145. }
  146. bool
  147. clang::analyze_format_string::ParseLengthModifier(FormatSpecifier &FS,
  148. const char *&I,
  149. const char *E,
  150. const LangOptions &LO,
  151. bool IsScanf) {
  152. LengthModifier::Kind lmKind = LengthModifier::None;
  153. const char *lmPosition = I;
  154. switch (*I) {
  155. default:
  156. return false;
  157. case 'h':
  158. ++I;
  159. lmKind = (I != E && *I == 'h') ? (++I, LengthModifier::AsChar)
  160. : LengthModifier::AsShort;
  161. break;
  162. case 'l':
  163. ++I;
  164. lmKind = (I != E && *I == 'l') ? (++I, LengthModifier::AsLongLong)
  165. : LengthModifier::AsLong;
  166. break;
  167. case 'j': lmKind = LengthModifier::AsIntMax; ++I; break;
  168. case 'z': lmKind = LengthModifier::AsSizeT; ++I; break;
  169. case 't': lmKind = LengthModifier::AsPtrDiff; ++I; break;
  170. case 'L': lmKind = LengthModifier::AsLongDouble; ++I; break;
  171. case 'q': lmKind = LengthModifier::AsQuad; ++I; break;
  172. case 'a':
  173. if (IsScanf && !LO.C99 && !LO.CPlusPlus0x) {
  174. // For scanf in C90, look at the next character to see if this should
  175. // be parsed as the GNU extension 'a' length modifier. If not, this
  176. // will be parsed as a conversion specifier.
  177. ++I;
  178. if (I != E && (*I == 's' || *I == 'S' || *I == '[')) {
  179. lmKind = LengthModifier::AsAllocate;
  180. break;
  181. }
  182. --I;
  183. }
  184. return false;
  185. case 'm':
  186. if (IsScanf) {
  187. lmKind = LengthModifier::AsMAllocate;
  188. ++I;
  189. break;
  190. }
  191. return false;
  192. }
  193. LengthModifier lm(lmPosition, lmKind);
  194. FS.setLengthModifier(lm);
  195. return true;
  196. }
  197. //===----------------------------------------------------------------------===//
  198. // Methods on ArgType.
  199. //===----------------------------------------------------------------------===//
  200. bool ArgType::matchesType(ASTContext &C, QualType argTy) const {
  201. switch (K) {
  202. case InvalidTy:
  203. llvm_unreachable("ArgType must be valid");
  204. case UnknownTy:
  205. return true;
  206. case AnyCharTy: {
  207. if (const EnumType *ETy = argTy->getAs<EnumType>())
  208. argTy = ETy->getDecl()->getIntegerType();
  209. if (const BuiltinType *BT = argTy->getAs<BuiltinType>())
  210. switch (BT->getKind()) {
  211. default:
  212. break;
  213. case BuiltinType::Char_S:
  214. case BuiltinType::SChar:
  215. case BuiltinType::UChar:
  216. case BuiltinType::Char_U:
  217. return true;
  218. }
  219. return false;
  220. }
  221. case SpecificTy: {
  222. if (const EnumType *ETy = argTy->getAs<EnumType>())
  223. argTy = ETy->getDecl()->getIntegerType();
  224. argTy = C.getCanonicalType(argTy).getUnqualifiedType();
  225. if (const PointerType *PTy = argTy->getAs<PointerType>()) {
  226. // Strip volatile qualifier from pointee type.
  227. QualType Pointee = PTy->getPointeeType();
  228. Pointee.removeLocalVolatile();
  229. argTy = C.getPointerType(Pointee);
  230. }
  231. if (T == argTy)
  232. return true;
  233. // Check for "compatible types".
  234. if (const BuiltinType *BT = argTy->getAs<BuiltinType>())
  235. switch (BT->getKind()) {
  236. default:
  237. break;
  238. case BuiltinType::Char_S:
  239. case BuiltinType::SChar:
  240. case BuiltinType::Char_U:
  241. case BuiltinType::UChar:
  242. return T == C.UnsignedCharTy || T == C.SignedCharTy;
  243. case BuiltinType::Short:
  244. return T == C.UnsignedShortTy;
  245. case BuiltinType::UShort:
  246. return T == C.ShortTy;
  247. case BuiltinType::Int:
  248. return T == C.UnsignedIntTy;
  249. case BuiltinType::UInt:
  250. return T == C.IntTy;
  251. case BuiltinType::Long:
  252. return T == C.UnsignedLongTy;
  253. case BuiltinType::ULong:
  254. return T == C.LongTy;
  255. case BuiltinType::LongLong:
  256. return T == C.UnsignedLongLongTy;
  257. case BuiltinType::ULongLong:
  258. return T == C.LongLongTy;
  259. }
  260. return false;
  261. }
  262. case CStrTy: {
  263. const PointerType *PT = argTy->getAs<PointerType>();
  264. if (!PT)
  265. return false;
  266. QualType pointeeTy = PT->getPointeeType();
  267. if (const BuiltinType *BT = pointeeTy->getAs<BuiltinType>())
  268. switch (BT->getKind()) {
  269. case BuiltinType::Void:
  270. case BuiltinType::Char_U:
  271. case BuiltinType::UChar:
  272. case BuiltinType::Char_S:
  273. case BuiltinType::SChar:
  274. return true;
  275. default:
  276. break;
  277. }
  278. return false;
  279. }
  280. case WCStrTy: {
  281. const PointerType *PT = argTy->getAs<PointerType>();
  282. if (!PT)
  283. return false;
  284. QualType pointeeTy =
  285. C.getCanonicalType(PT->getPointeeType()).getUnqualifiedType();
  286. return pointeeTy == C.getWCharType();
  287. }
  288. case WIntTy: {
  289. QualType PromoArg =
  290. argTy->isPromotableIntegerType()
  291. ? C.getPromotedIntegerType(argTy) : argTy;
  292. QualType WInt = C.getCanonicalType(C.getWIntType()).getUnqualifiedType();
  293. PromoArg = C.getCanonicalType(PromoArg).getUnqualifiedType();
  294. // If the promoted argument is the corresponding signed type of the
  295. // wint_t type, then it should match.
  296. if (PromoArg->hasSignedIntegerRepresentation() &&
  297. C.getCorrespondingUnsignedType(PromoArg) == WInt)
  298. return true;
  299. return WInt == PromoArg;
  300. }
  301. case CPointerTy:
  302. return argTy->isPointerType() || argTy->isObjCObjectPointerType() ||
  303. argTy->isBlockPointerType() || argTy->isNullPtrType();
  304. case ObjCPointerTy: {
  305. if (argTy->getAs<ObjCObjectPointerType>() ||
  306. argTy->getAs<BlockPointerType>())
  307. return true;
  308. // Handle implicit toll-free bridging.
  309. if (const PointerType *PT = argTy->getAs<PointerType>()) {
  310. // Things such as CFTypeRef are really just opaque pointers
  311. // to C structs representing CF types that can often be bridged
  312. // to Objective-C objects. Since the compiler doesn't know which
  313. // structs can be toll-free bridged, we just accept them all.
  314. QualType pointee = PT->getPointeeType();
  315. if (pointee->getAsStructureType() || pointee->isVoidType())
  316. return true;
  317. }
  318. return false;
  319. }
  320. }
  321. llvm_unreachable("Invalid ArgType Kind!");
  322. }
  323. QualType ArgType::getRepresentativeType(ASTContext &C) const {
  324. switch (K) {
  325. case InvalidTy:
  326. llvm_unreachable("No representative type for Invalid ArgType");
  327. case UnknownTy:
  328. return QualType();
  329. case AnyCharTy:
  330. return C.CharTy;
  331. case SpecificTy:
  332. return T;
  333. case CStrTy:
  334. return C.getPointerType(C.CharTy);
  335. case WCStrTy:
  336. return C.getPointerType(C.getWCharType());
  337. case ObjCPointerTy:
  338. return C.ObjCBuiltinIdTy;
  339. case CPointerTy:
  340. return C.VoidPtrTy;
  341. case WIntTy: {
  342. return C.getWIntType();
  343. }
  344. }
  345. llvm_unreachable("Invalid ArgType Kind!");
  346. }
  347. std::string ArgType::getRepresentativeTypeName(ASTContext &C) const {
  348. std::string S = getRepresentativeType(C).getAsString();
  349. if (Name && S != Name)
  350. return std::string("'") + Name + "' (aka '" + S + "')";
  351. return std::string("'") + S + "'";
  352. }
  353. //===----------------------------------------------------------------------===//
  354. // Methods on OptionalAmount.
  355. //===----------------------------------------------------------------------===//
  356. ArgType
  357. analyze_format_string::OptionalAmount::getArgType(ASTContext &Ctx) const {
  358. return Ctx.IntTy;
  359. }
  360. //===----------------------------------------------------------------------===//
  361. // Methods on LengthModifier.
  362. //===----------------------------------------------------------------------===//
  363. const char *
  364. analyze_format_string::LengthModifier::toString() const {
  365. switch (kind) {
  366. case AsChar:
  367. return "hh";
  368. case AsShort:
  369. return "h";
  370. case AsLong: // or AsWideChar
  371. return "l";
  372. case AsLongLong:
  373. return "ll";
  374. case AsQuad:
  375. return "q";
  376. case AsIntMax:
  377. return "j";
  378. case AsSizeT:
  379. return "z";
  380. case AsPtrDiff:
  381. return "t";
  382. case AsLongDouble:
  383. return "L";
  384. case AsAllocate:
  385. return "a";
  386. case AsMAllocate:
  387. return "m";
  388. case None:
  389. return "";
  390. }
  391. return NULL;
  392. }
  393. //===----------------------------------------------------------------------===//
  394. // Methods on ConversionSpecifier.
  395. //===----------------------------------------------------------------------===//
  396. const char *ConversionSpecifier::toString() const {
  397. switch (kind) {
  398. case dArg: return "d";
  399. case iArg: return "i";
  400. case oArg: return "o";
  401. case uArg: return "u";
  402. case xArg: return "x";
  403. case XArg: return "X";
  404. case fArg: return "f";
  405. case FArg: return "F";
  406. case eArg: return "e";
  407. case EArg: return "E";
  408. case gArg: return "g";
  409. case GArg: return "G";
  410. case aArg: return "a";
  411. case AArg: return "A";
  412. case cArg: return "c";
  413. case sArg: return "s";
  414. case pArg: return "p";
  415. case nArg: return "n";
  416. case PercentArg: return "%";
  417. case ScanListArg: return "[";
  418. case InvalidSpecifier: return NULL;
  419. // MacOS X unicode extensions.
  420. case CArg: return "C";
  421. case SArg: return "S";
  422. // Objective-C specific specifiers.
  423. case ObjCObjArg: return "@";
  424. // GlibC specific specifiers.
  425. case PrintErrno: return "m";
  426. }
  427. return NULL;
  428. }
  429. //===----------------------------------------------------------------------===//
  430. // Methods on OptionalAmount.
  431. //===----------------------------------------------------------------------===//
  432. void OptionalAmount::toString(raw_ostream &os) const {
  433. switch (hs) {
  434. case Invalid:
  435. case NotSpecified:
  436. return;
  437. case Arg:
  438. if (UsesDotPrefix)
  439. os << ".";
  440. if (usesPositionalArg())
  441. os << "*" << getPositionalArgIndex() << "$";
  442. else
  443. os << "*";
  444. break;
  445. case Constant:
  446. if (UsesDotPrefix)
  447. os << ".";
  448. os << amt;
  449. break;
  450. }
  451. }
  452. bool FormatSpecifier::hasValidLengthModifier() const {
  453. switch (LM.getKind()) {
  454. case LengthModifier::None:
  455. return true;
  456. // Handle most integer flags
  457. case LengthModifier::AsChar:
  458. case LengthModifier::AsShort:
  459. case LengthModifier::AsLongLong:
  460. case LengthModifier::AsQuad:
  461. case LengthModifier::AsIntMax:
  462. case LengthModifier::AsSizeT:
  463. case LengthModifier::AsPtrDiff:
  464. switch (CS.getKind()) {
  465. case ConversionSpecifier::dArg:
  466. case ConversionSpecifier::iArg:
  467. case ConversionSpecifier::oArg:
  468. case ConversionSpecifier::uArg:
  469. case ConversionSpecifier::xArg:
  470. case ConversionSpecifier::XArg:
  471. case ConversionSpecifier::nArg:
  472. return true;
  473. default:
  474. return false;
  475. }
  476. // Handle 'l' flag
  477. case LengthModifier::AsLong:
  478. switch (CS.getKind()) {
  479. case ConversionSpecifier::dArg:
  480. case ConversionSpecifier::iArg:
  481. case ConversionSpecifier::oArg:
  482. case ConversionSpecifier::uArg:
  483. case ConversionSpecifier::xArg:
  484. case ConversionSpecifier::XArg:
  485. case ConversionSpecifier::aArg:
  486. case ConversionSpecifier::AArg:
  487. case ConversionSpecifier::fArg:
  488. case ConversionSpecifier::FArg:
  489. case ConversionSpecifier::eArg:
  490. case ConversionSpecifier::EArg:
  491. case ConversionSpecifier::gArg:
  492. case ConversionSpecifier::GArg:
  493. case ConversionSpecifier::nArg:
  494. case ConversionSpecifier::cArg:
  495. case ConversionSpecifier::sArg:
  496. case ConversionSpecifier::ScanListArg:
  497. return true;
  498. default:
  499. return false;
  500. }
  501. case LengthModifier::AsLongDouble:
  502. switch (CS.getKind()) {
  503. case ConversionSpecifier::aArg:
  504. case ConversionSpecifier::AArg:
  505. case ConversionSpecifier::fArg:
  506. case ConversionSpecifier::FArg:
  507. case ConversionSpecifier::eArg:
  508. case ConversionSpecifier::EArg:
  509. case ConversionSpecifier::gArg:
  510. case ConversionSpecifier::GArg:
  511. return true;
  512. // GNU extension.
  513. case ConversionSpecifier::dArg:
  514. case ConversionSpecifier::iArg:
  515. case ConversionSpecifier::oArg:
  516. case ConversionSpecifier::uArg:
  517. case ConversionSpecifier::xArg:
  518. case ConversionSpecifier::XArg:
  519. return true;
  520. default:
  521. return false;
  522. }
  523. case LengthModifier::AsAllocate:
  524. switch (CS.getKind()) {
  525. case ConversionSpecifier::sArg:
  526. case ConversionSpecifier::SArg:
  527. case ConversionSpecifier::ScanListArg:
  528. return true;
  529. default:
  530. return false;
  531. }
  532. case LengthModifier::AsMAllocate:
  533. switch (CS.getKind()) {
  534. case ConversionSpecifier::cArg:
  535. case ConversionSpecifier::CArg:
  536. case ConversionSpecifier::sArg:
  537. case ConversionSpecifier::SArg:
  538. case ConversionSpecifier::ScanListArg:
  539. return true;
  540. default:
  541. return false;
  542. }
  543. }
  544. llvm_unreachable("Invalid LengthModifier Kind!");
  545. }
  546. bool FormatSpecifier::hasStandardLengthModifier() const {
  547. switch (LM.getKind()) {
  548. case LengthModifier::None:
  549. case LengthModifier::AsChar:
  550. case LengthModifier::AsShort:
  551. case LengthModifier::AsLong:
  552. case LengthModifier::AsLongLong:
  553. case LengthModifier::AsIntMax:
  554. case LengthModifier::AsSizeT:
  555. case LengthModifier::AsPtrDiff:
  556. case LengthModifier::AsLongDouble:
  557. return true;
  558. case LengthModifier::AsAllocate:
  559. case LengthModifier::AsMAllocate:
  560. case LengthModifier::AsQuad:
  561. return false;
  562. }
  563. llvm_unreachable("Invalid LengthModifier Kind!");
  564. }
  565. bool FormatSpecifier::hasStandardConversionSpecifier(const LangOptions &LangOpt) const {
  566. switch (CS.getKind()) {
  567. case ConversionSpecifier::cArg:
  568. case ConversionSpecifier::dArg:
  569. case ConversionSpecifier::iArg:
  570. case ConversionSpecifier::oArg:
  571. case ConversionSpecifier::uArg:
  572. case ConversionSpecifier::xArg:
  573. case ConversionSpecifier::XArg:
  574. case ConversionSpecifier::fArg:
  575. case ConversionSpecifier::FArg:
  576. case ConversionSpecifier::eArg:
  577. case ConversionSpecifier::EArg:
  578. case ConversionSpecifier::gArg:
  579. case ConversionSpecifier::GArg:
  580. case ConversionSpecifier::aArg:
  581. case ConversionSpecifier::AArg:
  582. case ConversionSpecifier::sArg:
  583. case ConversionSpecifier::pArg:
  584. case ConversionSpecifier::nArg:
  585. case ConversionSpecifier::ObjCObjArg:
  586. case ConversionSpecifier::ScanListArg:
  587. case ConversionSpecifier::PercentArg:
  588. return true;
  589. case ConversionSpecifier::CArg:
  590. case ConversionSpecifier::SArg:
  591. return LangOpt.ObjC1 || LangOpt.ObjC2;
  592. case ConversionSpecifier::InvalidSpecifier:
  593. case ConversionSpecifier::PrintErrno:
  594. return false;
  595. }
  596. llvm_unreachable("Invalid ConversionSpecifier Kind!");
  597. }
  598. bool FormatSpecifier::hasStandardLengthConversionCombination() const {
  599. if (LM.getKind() == LengthModifier::AsLongDouble) {
  600. switch(CS.getKind()) {
  601. case ConversionSpecifier::dArg:
  602. case ConversionSpecifier::iArg:
  603. case ConversionSpecifier::oArg:
  604. case ConversionSpecifier::uArg:
  605. case ConversionSpecifier::xArg:
  606. case ConversionSpecifier::XArg:
  607. return false;
  608. default:
  609. return true;
  610. }
  611. }
  612. return true;
  613. }
  614. bool FormatSpecifier::namedTypeToLengthModifier(QualType QT,
  615. LengthModifier &LM) {
  616. assert(isa<TypedefType>(QT) && "Expected a TypedefType");
  617. const TypedefNameDecl *Typedef = cast<TypedefType>(QT)->getDecl();
  618. for (;;) {
  619. const IdentifierInfo *Identifier = Typedef->getIdentifier();
  620. if (Identifier->getName() == "size_t") {
  621. LM.setKind(LengthModifier::AsSizeT);
  622. return true;
  623. } else if (Identifier->getName() == "ssize_t") {
  624. // Not C99, but common in Unix.
  625. LM.setKind(LengthModifier::AsSizeT);
  626. return true;
  627. } else if (Identifier->getName() == "intmax_t") {
  628. LM.setKind(LengthModifier::AsIntMax);
  629. return true;
  630. } else if (Identifier->getName() == "uintmax_t") {
  631. LM.setKind(LengthModifier::AsIntMax);
  632. return true;
  633. } else if (Identifier->getName() == "ptrdiff_t") {
  634. LM.setKind(LengthModifier::AsPtrDiff);
  635. return true;
  636. }
  637. QualType T = Typedef->getUnderlyingType();
  638. if (!isa<TypedefType>(T))
  639. break;
  640. Typedef = cast<TypedefType>(T)->getDecl();
  641. }
  642. return false;
  643. }