FormatString.cpp 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754
  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. if (Ptr) {
  202. // It has to be a pointer.
  203. const PointerType *PT = argTy->getAs<PointerType>();
  204. if (!PT)
  205. return false;
  206. // We cannot write through a const qualified pointer.
  207. if (PT->getPointeeType().isConstQualified())
  208. return false;
  209. argTy = PT->getPointeeType();
  210. }
  211. switch (K) {
  212. case InvalidTy:
  213. llvm_unreachable("ArgType must be valid");
  214. case UnknownTy:
  215. return true;
  216. case AnyCharTy: {
  217. if (const EnumType *ETy = argTy->getAs<EnumType>())
  218. argTy = ETy->getDecl()->getIntegerType();
  219. if (const BuiltinType *BT = argTy->getAs<BuiltinType>())
  220. switch (BT->getKind()) {
  221. default:
  222. break;
  223. case BuiltinType::Char_S:
  224. case BuiltinType::SChar:
  225. case BuiltinType::UChar:
  226. case BuiltinType::Char_U:
  227. return true;
  228. }
  229. return false;
  230. }
  231. case SpecificTy: {
  232. if (const EnumType *ETy = argTy->getAs<EnumType>())
  233. argTy = ETy->getDecl()->getIntegerType();
  234. argTy = C.getCanonicalType(argTy).getUnqualifiedType();
  235. if (T == argTy)
  236. return true;
  237. // Check for "compatible types".
  238. if (const BuiltinType *BT = argTy->getAs<BuiltinType>())
  239. switch (BT->getKind()) {
  240. default:
  241. break;
  242. case BuiltinType::Char_S:
  243. case BuiltinType::SChar:
  244. case BuiltinType::Char_U:
  245. case BuiltinType::UChar:
  246. return T == C.UnsignedCharTy || T == C.SignedCharTy;
  247. case BuiltinType::Short:
  248. return T == C.UnsignedShortTy;
  249. case BuiltinType::UShort:
  250. return T == C.ShortTy;
  251. case BuiltinType::Int:
  252. return T == C.UnsignedIntTy;
  253. case BuiltinType::UInt:
  254. return T == C.IntTy;
  255. case BuiltinType::Long:
  256. return T == C.UnsignedLongTy;
  257. case BuiltinType::ULong:
  258. return T == C.LongTy;
  259. case BuiltinType::LongLong:
  260. return T == C.UnsignedLongLongTy;
  261. case BuiltinType::ULongLong:
  262. return T == C.LongLongTy;
  263. }
  264. return false;
  265. }
  266. case CStrTy: {
  267. const PointerType *PT = argTy->getAs<PointerType>();
  268. if (!PT)
  269. return false;
  270. QualType pointeeTy = PT->getPointeeType();
  271. if (const BuiltinType *BT = pointeeTy->getAs<BuiltinType>())
  272. switch (BT->getKind()) {
  273. case BuiltinType::Void:
  274. case BuiltinType::Char_U:
  275. case BuiltinType::UChar:
  276. case BuiltinType::Char_S:
  277. case BuiltinType::SChar:
  278. return true;
  279. default:
  280. break;
  281. }
  282. return false;
  283. }
  284. case WCStrTy: {
  285. const PointerType *PT = argTy->getAs<PointerType>();
  286. if (!PT)
  287. return false;
  288. QualType pointeeTy =
  289. C.getCanonicalType(PT->getPointeeType()).getUnqualifiedType();
  290. return pointeeTy == C.getWCharType();
  291. }
  292. case WIntTy: {
  293. QualType PromoArg =
  294. argTy->isPromotableIntegerType()
  295. ? C.getPromotedIntegerType(argTy) : argTy;
  296. QualType WInt = C.getCanonicalType(C.getWIntType()).getUnqualifiedType();
  297. PromoArg = C.getCanonicalType(PromoArg).getUnqualifiedType();
  298. // If the promoted argument is the corresponding signed type of the
  299. // wint_t type, then it should match.
  300. if (PromoArg->hasSignedIntegerRepresentation() &&
  301. C.getCorrespondingUnsignedType(PromoArg) == WInt)
  302. return true;
  303. return WInt == PromoArg;
  304. }
  305. case CPointerTy:
  306. return argTy->isPointerType() || argTy->isObjCObjectPointerType() ||
  307. argTy->isBlockPointerType() || argTy->isNullPtrType();
  308. case ObjCPointerTy: {
  309. if (argTy->getAs<ObjCObjectPointerType>() ||
  310. argTy->getAs<BlockPointerType>())
  311. return true;
  312. // Handle implicit toll-free bridging.
  313. if (const PointerType *PT = argTy->getAs<PointerType>()) {
  314. // Things such as CFTypeRef are really just opaque pointers
  315. // to C structs representing CF types that can often be bridged
  316. // to Objective-C objects. Since the compiler doesn't know which
  317. // structs can be toll-free bridged, we just accept them all.
  318. QualType pointee = PT->getPointeeType();
  319. if (pointee->getAsStructureType() || pointee->isVoidType())
  320. return true;
  321. }
  322. return false;
  323. }
  324. }
  325. llvm_unreachable("Invalid ArgType Kind!");
  326. }
  327. QualType ArgType::getRepresentativeType(ASTContext &C) const {
  328. QualType Res;
  329. switch (K) {
  330. case InvalidTy:
  331. llvm_unreachable("No representative type for Invalid ArgType");
  332. case UnknownTy:
  333. llvm_unreachable("No representative type for Unknown ArgType");
  334. case AnyCharTy:
  335. Res = C.CharTy;
  336. break;
  337. case SpecificTy:
  338. Res = T;
  339. break;
  340. case CStrTy:
  341. Res = C.getPointerType(C.CharTy);
  342. break;
  343. case WCStrTy:
  344. Res = C.getPointerType(C.getWCharType());
  345. break;
  346. case ObjCPointerTy:
  347. Res = C.ObjCBuiltinIdTy;
  348. break;
  349. case CPointerTy:
  350. Res = C.VoidPtrTy;
  351. break;
  352. case WIntTy: {
  353. Res = C.getWIntType();
  354. break;
  355. }
  356. }
  357. if (Ptr)
  358. Res = C.getPointerType(Res);
  359. return Res;
  360. }
  361. std::string ArgType::getRepresentativeTypeName(ASTContext &C) const {
  362. std::string S = getRepresentativeType(C).getAsString();
  363. std::string Alias;
  364. if (Name) {
  365. // Use a specific name for this type, e.g. "size_t".
  366. Alias = Name;
  367. if (Ptr) {
  368. // If ArgType is actually a pointer to T, append an asterisk.
  369. Alias += (Alias[Alias.size()-1] == '*') ? "*" : " *";
  370. }
  371. // If Alias is the same as the underlying type, e.g. wchar_t, then drop it.
  372. if (S == Alias)
  373. Alias.clear();
  374. }
  375. if (!Alias.empty())
  376. return std::string("'") + Alias + "' (aka '" + S + "')";
  377. return std::string("'") + S + "'";
  378. }
  379. //===----------------------------------------------------------------------===//
  380. // Methods on OptionalAmount.
  381. //===----------------------------------------------------------------------===//
  382. ArgType
  383. analyze_format_string::OptionalAmount::getArgType(ASTContext &Ctx) const {
  384. return Ctx.IntTy;
  385. }
  386. //===----------------------------------------------------------------------===//
  387. // Methods on LengthModifier.
  388. //===----------------------------------------------------------------------===//
  389. const char *
  390. analyze_format_string::LengthModifier::toString() const {
  391. switch (kind) {
  392. case AsChar:
  393. return "hh";
  394. case AsShort:
  395. return "h";
  396. case AsLong: // or AsWideChar
  397. return "l";
  398. case AsLongLong:
  399. return "ll";
  400. case AsQuad:
  401. return "q";
  402. case AsIntMax:
  403. return "j";
  404. case AsSizeT:
  405. return "z";
  406. case AsPtrDiff:
  407. return "t";
  408. case AsLongDouble:
  409. return "L";
  410. case AsAllocate:
  411. return "a";
  412. case AsMAllocate:
  413. return "m";
  414. case None:
  415. return "";
  416. }
  417. return NULL;
  418. }
  419. //===----------------------------------------------------------------------===//
  420. // Methods on ConversionSpecifier.
  421. //===----------------------------------------------------------------------===//
  422. const char *ConversionSpecifier::toString() const {
  423. switch (kind) {
  424. case dArg: return "d";
  425. case iArg: return "i";
  426. case oArg: return "o";
  427. case uArg: return "u";
  428. case xArg: return "x";
  429. case XArg: return "X";
  430. case fArg: return "f";
  431. case FArg: return "F";
  432. case eArg: return "e";
  433. case EArg: return "E";
  434. case gArg: return "g";
  435. case GArg: return "G";
  436. case aArg: return "a";
  437. case AArg: return "A";
  438. case cArg: return "c";
  439. case sArg: return "s";
  440. case pArg: return "p";
  441. case nArg: return "n";
  442. case PercentArg: return "%";
  443. case ScanListArg: return "[";
  444. case InvalidSpecifier: return NULL;
  445. // MacOS X unicode extensions.
  446. case CArg: return "C";
  447. case SArg: return "S";
  448. // Objective-C specific specifiers.
  449. case ObjCObjArg: return "@";
  450. // GlibC specific specifiers.
  451. case PrintErrno: return "m";
  452. }
  453. return NULL;
  454. }
  455. //===----------------------------------------------------------------------===//
  456. // Methods on OptionalAmount.
  457. //===----------------------------------------------------------------------===//
  458. void OptionalAmount::toString(raw_ostream &os) const {
  459. switch (hs) {
  460. case Invalid:
  461. case NotSpecified:
  462. return;
  463. case Arg:
  464. if (UsesDotPrefix)
  465. os << ".";
  466. if (usesPositionalArg())
  467. os << "*" << getPositionalArgIndex() << "$";
  468. else
  469. os << "*";
  470. break;
  471. case Constant:
  472. if (UsesDotPrefix)
  473. os << ".";
  474. os << amt;
  475. break;
  476. }
  477. }
  478. bool FormatSpecifier::hasValidLengthModifier() const {
  479. switch (LM.getKind()) {
  480. case LengthModifier::None:
  481. return true;
  482. // Handle most integer flags
  483. case LengthModifier::AsChar:
  484. case LengthModifier::AsShort:
  485. case LengthModifier::AsLongLong:
  486. case LengthModifier::AsQuad:
  487. case LengthModifier::AsIntMax:
  488. case LengthModifier::AsSizeT:
  489. case LengthModifier::AsPtrDiff:
  490. switch (CS.getKind()) {
  491. case ConversionSpecifier::dArg:
  492. case ConversionSpecifier::iArg:
  493. case ConversionSpecifier::oArg:
  494. case ConversionSpecifier::uArg:
  495. case ConversionSpecifier::xArg:
  496. case ConversionSpecifier::XArg:
  497. case ConversionSpecifier::nArg:
  498. return true;
  499. default:
  500. return false;
  501. }
  502. // Handle 'l' flag
  503. case LengthModifier::AsLong:
  504. switch (CS.getKind()) {
  505. case ConversionSpecifier::dArg:
  506. case ConversionSpecifier::iArg:
  507. case ConversionSpecifier::oArg:
  508. case ConversionSpecifier::uArg:
  509. case ConversionSpecifier::xArg:
  510. case ConversionSpecifier::XArg:
  511. case ConversionSpecifier::aArg:
  512. case ConversionSpecifier::AArg:
  513. case ConversionSpecifier::fArg:
  514. case ConversionSpecifier::FArg:
  515. case ConversionSpecifier::eArg:
  516. case ConversionSpecifier::EArg:
  517. case ConversionSpecifier::gArg:
  518. case ConversionSpecifier::GArg:
  519. case ConversionSpecifier::nArg:
  520. case ConversionSpecifier::cArg:
  521. case ConversionSpecifier::sArg:
  522. case ConversionSpecifier::ScanListArg:
  523. return true;
  524. default:
  525. return false;
  526. }
  527. case LengthModifier::AsLongDouble:
  528. switch (CS.getKind()) {
  529. case ConversionSpecifier::aArg:
  530. case ConversionSpecifier::AArg:
  531. case ConversionSpecifier::fArg:
  532. case ConversionSpecifier::FArg:
  533. case ConversionSpecifier::eArg:
  534. case ConversionSpecifier::EArg:
  535. case ConversionSpecifier::gArg:
  536. case ConversionSpecifier::GArg:
  537. return true;
  538. // GNU extension.
  539. case ConversionSpecifier::dArg:
  540. case ConversionSpecifier::iArg:
  541. case ConversionSpecifier::oArg:
  542. case ConversionSpecifier::uArg:
  543. case ConversionSpecifier::xArg:
  544. case ConversionSpecifier::XArg:
  545. return true;
  546. default:
  547. return false;
  548. }
  549. case LengthModifier::AsAllocate:
  550. switch (CS.getKind()) {
  551. case ConversionSpecifier::sArg:
  552. case ConversionSpecifier::SArg:
  553. case ConversionSpecifier::ScanListArg:
  554. return true;
  555. default:
  556. return false;
  557. }
  558. case LengthModifier::AsMAllocate:
  559. switch (CS.getKind()) {
  560. case ConversionSpecifier::cArg:
  561. case ConversionSpecifier::CArg:
  562. case ConversionSpecifier::sArg:
  563. case ConversionSpecifier::SArg:
  564. case ConversionSpecifier::ScanListArg:
  565. return true;
  566. default:
  567. return false;
  568. }
  569. }
  570. llvm_unreachable("Invalid LengthModifier Kind!");
  571. }
  572. bool FormatSpecifier::hasStandardLengthModifier() const {
  573. switch (LM.getKind()) {
  574. case LengthModifier::None:
  575. case LengthModifier::AsChar:
  576. case LengthModifier::AsShort:
  577. case LengthModifier::AsLong:
  578. case LengthModifier::AsLongLong:
  579. case LengthModifier::AsIntMax:
  580. case LengthModifier::AsSizeT:
  581. case LengthModifier::AsPtrDiff:
  582. case LengthModifier::AsLongDouble:
  583. return true;
  584. case LengthModifier::AsAllocate:
  585. case LengthModifier::AsMAllocate:
  586. case LengthModifier::AsQuad:
  587. return false;
  588. }
  589. llvm_unreachable("Invalid LengthModifier Kind!");
  590. }
  591. bool FormatSpecifier::hasStandardConversionSpecifier(const LangOptions &LangOpt) const {
  592. switch (CS.getKind()) {
  593. case ConversionSpecifier::cArg:
  594. case ConversionSpecifier::dArg:
  595. case ConversionSpecifier::iArg:
  596. case ConversionSpecifier::oArg:
  597. case ConversionSpecifier::uArg:
  598. case ConversionSpecifier::xArg:
  599. case ConversionSpecifier::XArg:
  600. case ConversionSpecifier::fArg:
  601. case ConversionSpecifier::FArg:
  602. case ConversionSpecifier::eArg:
  603. case ConversionSpecifier::EArg:
  604. case ConversionSpecifier::gArg:
  605. case ConversionSpecifier::GArg:
  606. case ConversionSpecifier::aArg:
  607. case ConversionSpecifier::AArg:
  608. case ConversionSpecifier::sArg:
  609. case ConversionSpecifier::pArg:
  610. case ConversionSpecifier::nArg:
  611. case ConversionSpecifier::ObjCObjArg:
  612. case ConversionSpecifier::ScanListArg:
  613. case ConversionSpecifier::PercentArg:
  614. return true;
  615. case ConversionSpecifier::CArg:
  616. case ConversionSpecifier::SArg:
  617. return LangOpt.ObjC1 || LangOpt.ObjC2;
  618. case ConversionSpecifier::InvalidSpecifier:
  619. case ConversionSpecifier::PrintErrno:
  620. return false;
  621. }
  622. llvm_unreachable("Invalid ConversionSpecifier Kind!");
  623. }
  624. bool FormatSpecifier::hasStandardLengthConversionCombination() const {
  625. if (LM.getKind() == LengthModifier::AsLongDouble) {
  626. switch(CS.getKind()) {
  627. case ConversionSpecifier::dArg:
  628. case ConversionSpecifier::iArg:
  629. case ConversionSpecifier::oArg:
  630. case ConversionSpecifier::uArg:
  631. case ConversionSpecifier::xArg:
  632. case ConversionSpecifier::XArg:
  633. return false;
  634. default:
  635. return true;
  636. }
  637. }
  638. return true;
  639. }
  640. bool FormatSpecifier::namedTypeToLengthModifier(QualType QT,
  641. LengthModifier &LM) {
  642. assert(isa<TypedefType>(QT) && "Expected a TypedefType");
  643. const TypedefNameDecl *Typedef = cast<TypedefType>(QT)->getDecl();
  644. for (;;) {
  645. const IdentifierInfo *Identifier = Typedef->getIdentifier();
  646. if (Identifier->getName() == "size_t") {
  647. LM.setKind(LengthModifier::AsSizeT);
  648. return true;
  649. } else if (Identifier->getName() == "ssize_t") {
  650. // Not C99, but common in Unix.
  651. LM.setKind(LengthModifier::AsSizeT);
  652. return true;
  653. } else if (Identifier->getName() == "intmax_t") {
  654. LM.setKind(LengthModifier::AsIntMax);
  655. return true;
  656. } else if (Identifier->getName() == "uintmax_t") {
  657. LM.setKind(LengthModifier::AsIntMax);
  658. return true;
  659. } else if (Identifier->getName() == "ptrdiff_t") {
  660. LM.setKind(LengthModifier::AsPtrDiff);
  661. return true;
  662. }
  663. QualType T = Typedef->getUnderlyingType();
  664. if (!isa<TypedefType>(T))
  665. break;
  666. Typedef = cast<TypedefType>(T)->getDecl();
  667. }
  668. return false;
  669. }