FormatString.cpp 32 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074
  1. // FormatString.cpp - Common stuff for handling printf/scanf formats -*- C++ -*-
  2. //
  3. // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
  4. // See https://llvm.org/LICENSE.txt for license information.
  5. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  6. //
  7. //===----------------------------------------------------------------------===//
  8. //
  9. // Shared details for processing format strings of printf and scanf
  10. // (and friends).
  11. //
  12. //===----------------------------------------------------------------------===//
  13. #include "FormatStringParsing.h"
  14. #include "clang/Basic/LangOptions.h"
  15. #include "clang/Basic/TargetInfo.h"
  16. #include "llvm/Support/ConvertUTF.h"
  17. #include <optional>
  18. using clang::analyze_format_string::ArgType;
  19. using clang::analyze_format_string::FormatStringHandler;
  20. using clang::analyze_format_string::FormatSpecifier;
  21. using clang::analyze_format_string::LengthModifier;
  22. using clang::analyze_format_string::OptionalAmount;
  23. using clang::analyze_format_string::ConversionSpecifier;
  24. using namespace clang;
  25. // Key function to FormatStringHandler.
  26. FormatStringHandler::~FormatStringHandler() {}
  27. //===----------------------------------------------------------------------===//
  28. // Functions for parsing format strings components in both printf and
  29. // scanf format strings.
  30. //===----------------------------------------------------------------------===//
  31. OptionalAmount
  32. clang::analyze_format_string::ParseAmount(const char *&Beg, const char *E) {
  33. const char *I = Beg;
  34. UpdateOnReturn <const char*> UpdateBeg(Beg, I);
  35. unsigned accumulator = 0;
  36. bool hasDigits = false;
  37. for ( ; I != E; ++I) {
  38. char c = *I;
  39. if (c >= '0' && c <= '9') {
  40. hasDigits = true;
  41. accumulator = (accumulator * 10) + (c - '0');
  42. continue;
  43. }
  44. if (hasDigits)
  45. return OptionalAmount(OptionalAmount::Constant, accumulator, Beg, I - Beg,
  46. false);
  47. break;
  48. }
  49. return OptionalAmount();
  50. }
  51. OptionalAmount
  52. clang::analyze_format_string::ParseNonPositionAmount(const char *&Beg,
  53. const char *E,
  54. unsigned &argIndex) {
  55. if (*Beg == '*') {
  56. ++Beg;
  57. return OptionalAmount(OptionalAmount::Arg, argIndex++, Beg, 0, false);
  58. }
  59. return ParseAmount(Beg, E);
  60. }
  61. OptionalAmount
  62. clang::analyze_format_string::ParsePositionAmount(FormatStringHandler &H,
  63. const char *Start,
  64. const char *&Beg,
  65. const char *E,
  66. PositionContext p) {
  67. if (*Beg == '*') {
  68. const char *I = Beg + 1;
  69. const OptionalAmount &Amt = ParseAmount(I, E);
  70. if (Amt.getHowSpecified() == OptionalAmount::NotSpecified) {
  71. H.HandleInvalidPosition(Beg, I - Beg, p);
  72. return OptionalAmount(false);
  73. }
  74. if (I == E) {
  75. // No more characters left?
  76. H.HandleIncompleteSpecifier(Start, E - Start);
  77. return OptionalAmount(false);
  78. }
  79. assert(Amt.getHowSpecified() == OptionalAmount::Constant);
  80. if (*I == '$') {
  81. // Handle positional arguments
  82. // Special case: '*0$', since this is an easy mistake.
  83. if (Amt.getConstantAmount() == 0) {
  84. H.HandleZeroPosition(Beg, I - Beg + 1);
  85. return OptionalAmount(false);
  86. }
  87. const char *Tmp = Beg;
  88. Beg = ++I;
  89. return OptionalAmount(OptionalAmount::Arg, Amt.getConstantAmount() - 1,
  90. Tmp, 0, true);
  91. }
  92. H.HandleInvalidPosition(Beg, I - Beg, p);
  93. return OptionalAmount(false);
  94. }
  95. return ParseAmount(Beg, E);
  96. }
  97. bool
  98. clang::analyze_format_string::ParseFieldWidth(FormatStringHandler &H,
  99. FormatSpecifier &CS,
  100. const char *Start,
  101. const char *&Beg, const char *E,
  102. unsigned *argIndex) {
  103. // FIXME: Support negative field widths.
  104. if (argIndex) {
  105. CS.setFieldWidth(ParseNonPositionAmount(Beg, E, *argIndex));
  106. }
  107. else {
  108. const OptionalAmount Amt =
  109. ParsePositionAmount(H, Start, Beg, E,
  110. analyze_format_string::FieldWidthPos);
  111. if (Amt.isInvalid())
  112. return true;
  113. CS.setFieldWidth(Amt);
  114. }
  115. return false;
  116. }
  117. bool
  118. clang::analyze_format_string::ParseArgPosition(FormatStringHandler &H,
  119. FormatSpecifier &FS,
  120. const char *Start,
  121. const char *&Beg,
  122. const char *E) {
  123. const char *I = Beg;
  124. const OptionalAmount &Amt = ParseAmount(I, E);
  125. if (I == E) {
  126. // No more characters left?
  127. H.HandleIncompleteSpecifier(Start, E - Start);
  128. return true;
  129. }
  130. if (Amt.getHowSpecified() == OptionalAmount::Constant && *(I++) == '$') {
  131. // Warn that positional arguments are non-standard.
  132. H.HandlePosition(Start, I - Start);
  133. // Special case: '%0$', since this is an easy mistake.
  134. if (Amt.getConstantAmount() == 0) {
  135. H.HandleZeroPosition(Start, I - Start);
  136. return true;
  137. }
  138. FS.setArgIndex(Amt.getConstantAmount() - 1);
  139. FS.setUsesPositionalArg();
  140. // Update the caller's pointer if we decided to consume
  141. // these characters.
  142. Beg = I;
  143. return false;
  144. }
  145. return false;
  146. }
  147. bool
  148. clang::analyze_format_string::ParseVectorModifier(FormatStringHandler &H,
  149. FormatSpecifier &FS,
  150. const char *&I,
  151. const char *E,
  152. const LangOptions &LO) {
  153. if (!LO.OpenCL)
  154. return false;
  155. const char *Start = I;
  156. if (*I == 'v') {
  157. ++I;
  158. if (I == E) {
  159. H.HandleIncompleteSpecifier(Start, E - Start);
  160. return true;
  161. }
  162. OptionalAmount NumElts = ParseAmount(I, E);
  163. if (NumElts.getHowSpecified() != OptionalAmount::Constant) {
  164. H.HandleIncompleteSpecifier(Start, E - Start);
  165. return true;
  166. }
  167. FS.setVectorNumElts(NumElts);
  168. }
  169. return false;
  170. }
  171. bool
  172. clang::analyze_format_string::ParseLengthModifier(FormatSpecifier &FS,
  173. const char *&I,
  174. const char *E,
  175. const LangOptions &LO,
  176. bool IsScanf) {
  177. LengthModifier::Kind lmKind = LengthModifier::None;
  178. const char *lmPosition = I;
  179. switch (*I) {
  180. default:
  181. return false;
  182. case 'h':
  183. ++I;
  184. if (I != E && *I == 'h') {
  185. ++I;
  186. lmKind = LengthModifier::AsChar;
  187. } else if (I != E && *I == 'l' && LO.OpenCL) {
  188. ++I;
  189. lmKind = LengthModifier::AsShortLong;
  190. } else {
  191. lmKind = LengthModifier::AsShort;
  192. }
  193. break;
  194. case 'l':
  195. ++I;
  196. if (I != E && *I == 'l') {
  197. ++I;
  198. lmKind = LengthModifier::AsLongLong;
  199. } else {
  200. lmKind = LengthModifier::AsLong;
  201. }
  202. break;
  203. case 'j': lmKind = LengthModifier::AsIntMax; ++I; break;
  204. case 'z': lmKind = LengthModifier::AsSizeT; ++I; break;
  205. case 't': lmKind = LengthModifier::AsPtrDiff; ++I; break;
  206. case 'L': lmKind = LengthModifier::AsLongDouble; ++I; break;
  207. case 'q': lmKind = LengthModifier::AsQuad; ++I; break;
  208. case 'a':
  209. if (IsScanf && !LO.C99 && !LO.CPlusPlus11) {
  210. // For scanf in C90, look at the next character to see if this should
  211. // be parsed as the GNU extension 'a' length modifier. If not, this
  212. // will be parsed as a conversion specifier.
  213. ++I;
  214. if (I != E && (*I == 's' || *I == 'S' || *I == '[')) {
  215. lmKind = LengthModifier::AsAllocate;
  216. break;
  217. }
  218. --I;
  219. }
  220. return false;
  221. case 'm':
  222. if (IsScanf) {
  223. lmKind = LengthModifier::AsMAllocate;
  224. ++I;
  225. break;
  226. }
  227. return false;
  228. // printf: AsInt64, AsInt32, AsInt3264
  229. // scanf: AsInt64
  230. case 'I':
  231. if (I + 1 != E && I + 2 != E) {
  232. if (I[1] == '6' && I[2] == '4') {
  233. I += 3;
  234. lmKind = LengthModifier::AsInt64;
  235. break;
  236. }
  237. if (IsScanf)
  238. return false;
  239. if (I[1] == '3' && I[2] == '2') {
  240. I += 3;
  241. lmKind = LengthModifier::AsInt32;
  242. break;
  243. }
  244. }
  245. ++I;
  246. lmKind = LengthModifier::AsInt3264;
  247. break;
  248. case 'w':
  249. lmKind = LengthModifier::AsWide; ++I; break;
  250. }
  251. LengthModifier lm(lmPosition, lmKind);
  252. FS.setLengthModifier(lm);
  253. return true;
  254. }
  255. bool clang::analyze_format_string::ParseUTF8InvalidSpecifier(
  256. const char *SpecifierBegin, const char *FmtStrEnd, unsigned &Len) {
  257. if (SpecifierBegin + 1 >= FmtStrEnd)
  258. return false;
  259. const llvm::UTF8 *SB =
  260. reinterpret_cast<const llvm::UTF8 *>(SpecifierBegin + 1);
  261. const llvm::UTF8 *SE = reinterpret_cast<const llvm::UTF8 *>(FmtStrEnd);
  262. const char FirstByte = *SB;
  263. // If the invalid specifier is a multibyte UTF-8 string, return the
  264. // total length accordingly so that the conversion specifier can be
  265. // properly updated to reflect a complete UTF-8 specifier.
  266. unsigned NumBytes = llvm::getNumBytesForUTF8(FirstByte);
  267. if (NumBytes == 1)
  268. return false;
  269. if (SB + NumBytes > SE)
  270. return false;
  271. Len = NumBytes + 1;
  272. return true;
  273. }
  274. //===----------------------------------------------------------------------===//
  275. // Methods on ArgType.
  276. //===----------------------------------------------------------------------===//
  277. clang::analyze_format_string::ArgType::MatchKind
  278. ArgType::matchesType(ASTContext &C, QualType argTy) const {
  279. // When using the format attribute in C++, you can receive a function or an
  280. // array that will necessarily decay to a pointer when passed to the final
  281. // format consumer. Apply decay before type comparison.
  282. if (argTy->canDecayToPointerType())
  283. argTy = C.getDecayedType(argTy);
  284. if (Ptr) {
  285. // It has to be a pointer.
  286. const PointerType *PT = argTy->getAs<PointerType>();
  287. if (!PT)
  288. return NoMatch;
  289. // We cannot write through a const qualified pointer.
  290. if (PT->getPointeeType().isConstQualified())
  291. return NoMatch;
  292. argTy = PT->getPointeeType();
  293. }
  294. switch (K) {
  295. case InvalidTy:
  296. llvm_unreachable("ArgType must be valid");
  297. case UnknownTy:
  298. return Match;
  299. case AnyCharTy: {
  300. if (const auto *ETy = argTy->getAs<EnumType>()) {
  301. // If the enum is incomplete we know nothing about the underlying type.
  302. // Assume that it's 'int'.
  303. if (!ETy->getDecl()->isComplete())
  304. return NoMatch;
  305. argTy = ETy->getDecl()->getIntegerType();
  306. }
  307. if (const auto *BT = argTy->getAs<BuiltinType>()) {
  308. // The types are perfectly matched?
  309. switch (BT->getKind()) {
  310. default:
  311. break;
  312. case BuiltinType::Char_S:
  313. case BuiltinType::SChar:
  314. case BuiltinType::UChar:
  315. case BuiltinType::Char_U:
  316. case BuiltinType::Bool:
  317. return Match;
  318. }
  319. // "Partially matched" because of promotions?
  320. if (!Ptr) {
  321. switch (BT->getKind()) {
  322. default:
  323. break;
  324. case BuiltinType::Int:
  325. case BuiltinType::UInt:
  326. return MatchPromotion;
  327. case BuiltinType::Short:
  328. case BuiltinType::UShort:
  329. case BuiltinType::WChar_S:
  330. case BuiltinType::WChar_U:
  331. return NoMatchPromotionTypeConfusion;
  332. }
  333. }
  334. }
  335. return NoMatch;
  336. }
  337. case SpecificTy: {
  338. if (const EnumType *ETy = argTy->getAs<EnumType>()) {
  339. // If the enum is incomplete we know nothing about the underlying type.
  340. // Assume that it's 'int'.
  341. if (!ETy->getDecl()->isComplete())
  342. argTy = C.IntTy;
  343. else
  344. argTy = ETy->getDecl()->getIntegerType();
  345. }
  346. argTy = C.getCanonicalType(argTy).getUnqualifiedType();
  347. if (T == argTy)
  348. return Match;
  349. if (const auto *BT = argTy->getAs<BuiltinType>()) {
  350. // Check if the only difference between them is signed vs unsigned
  351. // if true, we consider they are compatible.
  352. switch (BT->getKind()) {
  353. default:
  354. break;
  355. case BuiltinType::Char_S:
  356. case BuiltinType::SChar:
  357. case BuiltinType::Char_U:
  358. case BuiltinType::UChar:
  359. case BuiltinType::Bool:
  360. if (T == C.UnsignedShortTy || T == C.ShortTy)
  361. return NoMatchTypeConfusion;
  362. if (T == C.UnsignedCharTy || T == C.SignedCharTy)
  363. return Match;
  364. break;
  365. case BuiltinType::Short:
  366. if (T == C.UnsignedShortTy)
  367. return Match;
  368. break;
  369. case BuiltinType::UShort:
  370. if (T == C.ShortTy)
  371. return Match;
  372. break;
  373. case BuiltinType::Int:
  374. if (T == C.UnsignedIntTy)
  375. return Match;
  376. break;
  377. case BuiltinType::UInt:
  378. if (T == C.IntTy)
  379. return Match;
  380. break;
  381. case BuiltinType::Long:
  382. if (T == C.UnsignedLongTy)
  383. return Match;
  384. break;
  385. case BuiltinType::ULong:
  386. if (T == C.LongTy)
  387. return Match;
  388. break;
  389. case BuiltinType::LongLong:
  390. if (T == C.UnsignedLongLongTy)
  391. return Match;
  392. break;
  393. case BuiltinType::ULongLong:
  394. if (T == C.LongLongTy)
  395. return Match;
  396. break;
  397. }
  398. // "Partially matched" because of promotions?
  399. if (!Ptr) {
  400. switch (BT->getKind()) {
  401. default:
  402. break;
  403. case BuiltinType::Int:
  404. case BuiltinType::UInt:
  405. if (T == C.SignedCharTy || T == C.UnsignedCharTy ||
  406. T == C.ShortTy || T == C.UnsignedShortTy || T == C.WCharTy ||
  407. T == C.WideCharTy)
  408. return MatchPromotion;
  409. break;
  410. case BuiltinType::Short:
  411. case BuiltinType::UShort:
  412. if (T == C.SignedCharTy || T == C.UnsignedCharTy)
  413. return NoMatchPromotionTypeConfusion;
  414. break;
  415. case BuiltinType::WChar_U:
  416. case BuiltinType::WChar_S:
  417. if (T != C.WCharTy && T != C.WideCharTy)
  418. return NoMatchPromotionTypeConfusion;
  419. }
  420. }
  421. }
  422. return NoMatch;
  423. }
  424. case CStrTy: {
  425. const PointerType *PT = argTy->getAs<PointerType>();
  426. if (!PT)
  427. return NoMatch;
  428. QualType pointeeTy = PT->getPointeeType();
  429. if (const BuiltinType *BT = pointeeTy->getAs<BuiltinType>())
  430. switch (BT->getKind()) {
  431. case BuiltinType::Char_U:
  432. case BuiltinType::UChar:
  433. case BuiltinType::Char_S:
  434. case BuiltinType::SChar:
  435. return Match;
  436. default:
  437. break;
  438. }
  439. return NoMatch;
  440. }
  441. case WCStrTy: {
  442. const PointerType *PT = argTy->getAs<PointerType>();
  443. if (!PT)
  444. return NoMatch;
  445. QualType pointeeTy =
  446. C.getCanonicalType(PT->getPointeeType()).getUnqualifiedType();
  447. return pointeeTy == C.getWideCharType() ? Match : NoMatch;
  448. }
  449. case WIntTy: {
  450. QualType WInt = C.getCanonicalType(C.getWIntType()).getUnqualifiedType();
  451. if (C.getCanonicalType(argTy).getUnqualifiedType() == WInt)
  452. return Match;
  453. QualType PromoArg = C.isPromotableIntegerType(argTy)
  454. ? C.getPromotedIntegerType(argTy)
  455. : argTy;
  456. PromoArg = C.getCanonicalType(PromoArg).getUnqualifiedType();
  457. // If the promoted argument is the corresponding signed type of the
  458. // wint_t type, then it should match.
  459. if (PromoArg->hasSignedIntegerRepresentation() &&
  460. C.getCorrespondingUnsignedType(PromoArg) == WInt)
  461. return Match;
  462. return WInt == PromoArg ? Match : NoMatch;
  463. }
  464. case CPointerTy:
  465. if (argTy->isVoidPointerType()) {
  466. return Match;
  467. } if (argTy->isPointerType() || argTy->isObjCObjectPointerType() ||
  468. argTy->isBlockPointerType() || argTy->isNullPtrType()) {
  469. return NoMatchPedantic;
  470. } else {
  471. return NoMatch;
  472. }
  473. case ObjCPointerTy: {
  474. if (argTy->getAs<ObjCObjectPointerType>() ||
  475. argTy->getAs<BlockPointerType>())
  476. return Match;
  477. // Handle implicit toll-free bridging.
  478. if (const PointerType *PT = argTy->getAs<PointerType>()) {
  479. // Things such as CFTypeRef are really just opaque pointers
  480. // to C structs representing CF types that can often be bridged
  481. // to Objective-C objects. Since the compiler doesn't know which
  482. // structs can be toll-free bridged, we just accept them all.
  483. QualType pointee = PT->getPointeeType();
  484. if (pointee->getAsStructureType() || pointee->isVoidType())
  485. return Match;
  486. }
  487. return NoMatch;
  488. }
  489. }
  490. llvm_unreachable("Invalid ArgType Kind!");
  491. }
  492. ArgType ArgType::makeVectorType(ASTContext &C, unsigned NumElts) const {
  493. // Check for valid vector element types.
  494. if (T.isNull())
  495. return ArgType::Invalid();
  496. QualType Vec = C.getExtVectorType(T, NumElts);
  497. return ArgType(Vec, Name);
  498. }
  499. QualType ArgType::getRepresentativeType(ASTContext &C) const {
  500. QualType Res;
  501. switch (K) {
  502. case InvalidTy:
  503. llvm_unreachable("No representative type for Invalid ArgType");
  504. case UnknownTy:
  505. llvm_unreachable("No representative type for Unknown ArgType");
  506. case AnyCharTy:
  507. Res = C.CharTy;
  508. break;
  509. case SpecificTy:
  510. Res = T;
  511. break;
  512. case CStrTy:
  513. Res = C.getPointerType(C.CharTy);
  514. break;
  515. case WCStrTy:
  516. Res = C.getPointerType(C.getWideCharType());
  517. break;
  518. case ObjCPointerTy:
  519. Res = C.ObjCBuiltinIdTy;
  520. break;
  521. case CPointerTy:
  522. Res = C.VoidPtrTy;
  523. break;
  524. case WIntTy: {
  525. Res = C.getWIntType();
  526. break;
  527. }
  528. }
  529. if (Ptr)
  530. Res = C.getPointerType(Res);
  531. return Res;
  532. }
  533. std::string ArgType::getRepresentativeTypeName(ASTContext &C) const {
  534. std::string S = getRepresentativeType(C).getAsString(C.getPrintingPolicy());
  535. std::string Alias;
  536. if (Name) {
  537. // Use a specific name for this type, e.g. "size_t".
  538. Alias = Name;
  539. if (Ptr) {
  540. // If ArgType is actually a pointer to T, append an asterisk.
  541. Alias += (Alias[Alias.size()-1] == '*') ? "*" : " *";
  542. }
  543. // If Alias is the same as the underlying type, e.g. wchar_t, then drop it.
  544. if (S == Alias)
  545. Alias.clear();
  546. }
  547. if (!Alias.empty())
  548. return std::string("'") + Alias + "' (aka '" + S + "')";
  549. return std::string("'") + S + "'";
  550. }
  551. //===----------------------------------------------------------------------===//
  552. // Methods on OptionalAmount.
  553. //===----------------------------------------------------------------------===//
  554. ArgType
  555. analyze_format_string::OptionalAmount::getArgType(ASTContext &Ctx) const {
  556. return Ctx.IntTy;
  557. }
  558. //===----------------------------------------------------------------------===//
  559. // Methods on LengthModifier.
  560. //===----------------------------------------------------------------------===//
  561. const char *
  562. analyze_format_string::LengthModifier::toString() const {
  563. switch (kind) {
  564. case AsChar:
  565. return "hh";
  566. case AsShort:
  567. return "h";
  568. case AsShortLong:
  569. return "hl";
  570. case AsLong: // or AsWideChar
  571. return "l";
  572. case AsLongLong:
  573. return "ll";
  574. case AsQuad:
  575. return "q";
  576. case AsIntMax:
  577. return "j";
  578. case AsSizeT:
  579. return "z";
  580. case AsPtrDiff:
  581. return "t";
  582. case AsInt32:
  583. return "I32";
  584. case AsInt3264:
  585. return "I";
  586. case AsInt64:
  587. return "I64";
  588. case AsLongDouble:
  589. return "L";
  590. case AsAllocate:
  591. return "a";
  592. case AsMAllocate:
  593. return "m";
  594. case AsWide:
  595. return "w";
  596. case None:
  597. return "";
  598. }
  599. return nullptr;
  600. }
  601. //===----------------------------------------------------------------------===//
  602. // Methods on ConversionSpecifier.
  603. //===----------------------------------------------------------------------===//
  604. const char *ConversionSpecifier::toString() const {
  605. switch (kind) {
  606. case bArg: return "b";
  607. case BArg: return "B";
  608. case dArg: return "d";
  609. case DArg: return "D";
  610. case iArg: return "i";
  611. case oArg: return "o";
  612. case OArg: return "O";
  613. case uArg: return "u";
  614. case UArg: return "U";
  615. case xArg: return "x";
  616. case XArg: return "X";
  617. case fArg: return "f";
  618. case FArg: return "F";
  619. case eArg: return "e";
  620. case EArg: return "E";
  621. case gArg: return "g";
  622. case GArg: return "G";
  623. case aArg: return "a";
  624. case AArg: return "A";
  625. case cArg: return "c";
  626. case sArg: return "s";
  627. case pArg: return "p";
  628. case PArg:
  629. return "P";
  630. case nArg: return "n";
  631. case PercentArg: return "%";
  632. case ScanListArg: return "[";
  633. case InvalidSpecifier: return nullptr;
  634. // POSIX unicode extensions.
  635. case CArg: return "C";
  636. case SArg: return "S";
  637. // Objective-C specific specifiers.
  638. case ObjCObjArg: return "@";
  639. // FreeBSD kernel specific specifiers.
  640. case FreeBSDbArg: return "b";
  641. case FreeBSDDArg: return "D";
  642. case FreeBSDrArg: return "r";
  643. case FreeBSDyArg: return "y";
  644. // GlibC specific specifiers.
  645. case PrintErrno: return "m";
  646. // MS specific specifiers.
  647. case ZArg: return "Z";
  648. }
  649. return nullptr;
  650. }
  651. std::optional<ConversionSpecifier>
  652. ConversionSpecifier::getStandardSpecifier() const {
  653. ConversionSpecifier::Kind NewKind;
  654. switch (getKind()) {
  655. default:
  656. return std::nullopt;
  657. case DArg:
  658. NewKind = dArg;
  659. break;
  660. case UArg:
  661. NewKind = uArg;
  662. break;
  663. case OArg:
  664. NewKind = oArg;
  665. break;
  666. }
  667. ConversionSpecifier FixedCS(*this);
  668. FixedCS.setKind(NewKind);
  669. return FixedCS;
  670. }
  671. //===----------------------------------------------------------------------===//
  672. // Methods on OptionalAmount.
  673. //===----------------------------------------------------------------------===//
  674. void OptionalAmount::toString(raw_ostream &os) const {
  675. switch (hs) {
  676. case Invalid:
  677. case NotSpecified:
  678. return;
  679. case Arg:
  680. if (UsesDotPrefix)
  681. os << ".";
  682. if (usesPositionalArg())
  683. os << "*" << getPositionalArgIndex() << "$";
  684. else
  685. os << "*";
  686. break;
  687. case Constant:
  688. if (UsesDotPrefix)
  689. os << ".";
  690. os << amt;
  691. break;
  692. }
  693. }
  694. bool FormatSpecifier::hasValidLengthModifier(const TargetInfo &Target,
  695. const LangOptions &LO) const {
  696. switch (LM.getKind()) {
  697. case LengthModifier::None:
  698. return true;
  699. // Handle most integer flags
  700. case LengthModifier::AsShort:
  701. // Length modifier only applies to FP vectors.
  702. if (LO.OpenCL && CS.isDoubleArg())
  703. return !VectorNumElts.isInvalid();
  704. if (Target.getTriple().isOSMSVCRT()) {
  705. switch (CS.getKind()) {
  706. case ConversionSpecifier::cArg:
  707. case ConversionSpecifier::CArg:
  708. case ConversionSpecifier::sArg:
  709. case ConversionSpecifier::SArg:
  710. case ConversionSpecifier::ZArg:
  711. return true;
  712. default:
  713. break;
  714. }
  715. }
  716. [[fallthrough]];
  717. case LengthModifier::AsChar:
  718. case LengthModifier::AsLongLong:
  719. case LengthModifier::AsQuad:
  720. case LengthModifier::AsIntMax:
  721. case LengthModifier::AsSizeT:
  722. case LengthModifier::AsPtrDiff:
  723. switch (CS.getKind()) {
  724. case ConversionSpecifier::bArg:
  725. case ConversionSpecifier::BArg:
  726. case ConversionSpecifier::dArg:
  727. case ConversionSpecifier::DArg:
  728. case ConversionSpecifier::iArg:
  729. case ConversionSpecifier::oArg:
  730. case ConversionSpecifier::OArg:
  731. case ConversionSpecifier::uArg:
  732. case ConversionSpecifier::UArg:
  733. case ConversionSpecifier::xArg:
  734. case ConversionSpecifier::XArg:
  735. case ConversionSpecifier::nArg:
  736. return true;
  737. case ConversionSpecifier::FreeBSDrArg:
  738. case ConversionSpecifier::FreeBSDyArg:
  739. return Target.getTriple().isOSFreeBSD() || Target.getTriple().isPS();
  740. default:
  741. return false;
  742. }
  743. case LengthModifier::AsShortLong:
  744. return LO.OpenCL && !VectorNumElts.isInvalid();
  745. // Handle 'l' flag
  746. case LengthModifier::AsLong: // or AsWideChar
  747. if (CS.isDoubleArg()) {
  748. // Invalid for OpenCL FP scalars.
  749. if (LO.OpenCL && VectorNumElts.isInvalid())
  750. return false;
  751. return true;
  752. }
  753. switch (CS.getKind()) {
  754. case ConversionSpecifier::dArg:
  755. case ConversionSpecifier::DArg:
  756. case ConversionSpecifier::iArg:
  757. case ConversionSpecifier::oArg:
  758. case ConversionSpecifier::OArg:
  759. case ConversionSpecifier::uArg:
  760. case ConversionSpecifier::UArg:
  761. case ConversionSpecifier::xArg:
  762. case ConversionSpecifier::XArg:
  763. case ConversionSpecifier::nArg:
  764. case ConversionSpecifier::cArg:
  765. case ConversionSpecifier::sArg:
  766. case ConversionSpecifier::ScanListArg:
  767. case ConversionSpecifier::ZArg:
  768. return true;
  769. case ConversionSpecifier::FreeBSDrArg:
  770. case ConversionSpecifier::FreeBSDyArg:
  771. return Target.getTriple().isOSFreeBSD() || Target.getTriple().isPS();
  772. default:
  773. return false;
  774. }
  775. case LengthModifier::AsLongDouble:
  776. switch (CS.getKind()) {
  777. case ConversionSpecifier::aArg:
  778. case ConversionSpecifier::AArg:
  779. case ConversionSpecifier::fArg:
  780. case ConversionSpecifier::FArg:
  781. case ConversionSpecifier::eArg:
  782. case ConversionSpecifier::EArg:
  783. case ConversionSpecifier::gArg:
  784. case ConversionSpecifier::GArg:
  785. return true;
  786. // GNU libc extension.
  787. case ConversionSpecifier::dArg:
  788. case ConversionSpecifier::iArg:
  789. case ConversionSpecifier::oArg:
  790. case ConversionSpecifier::uArg:
  791. case ConversionSpecifier::xArg:
  792. case ConversionSpecifier::XArg:
  793. return !Target.getTriple().isOSDarwin() &&
  794. !Target.getTriple().isOSWindows();
  795. default:
  796. return false;
  797. }
  798. case LengthModifier::AsAllocate:
  799. switch (CS.getKind()) {
  800. case ConversionSpecifier::sArg:
  801. case ConversionSpecifier::SArg:
  802. case ConversionSpecifier::ScanListArg:
  803. return true;
  804. default:
  805. return false;
  806. }
  807. case LengthModifier::AsMAllocate:
  808. switch (CS.getKind()) {
  809. case ConversionSpecifier::cArg:
  810. case ConversionSpecifier::CArg:
  811. case ConversionSpecifier::sArg:
  812. case ConversionSpecifier::SArg:
  813. case ConversionSpecifier::ScanListArg:
  814. return true;
  815. default:
  816. return false;
  817. }
  818. case LengthModifier::AsInt32:
  819. case LengthModifier::AsInt3264:
  820. case LengthModifier::AsInt64:
  821. switch (CS.getKind()) {
  822. case ConversionSpecifier::dArg:
  823. case ConversionSpecifier::iArg:
  824. case ConversionSpecifier::oArg:
  825. case ConversionSpecifier::uArg:
  826. case ConversionSpecifier::xArg:
  827. case ConversionSpecifier::XArg:
  828. return Target.getTriple().isOSMSVCRT();
  829. default:
  830. return false;
  831. }
  832. case LengthModifier::AsWide:
  833. switch (CS.getKind()) {
  834. case ConversionSpecifier::cArg:
  835. case ConversionSpecifier::CArg:
  836. case ConversionSpecifier::sArg:
  837. case ConversionSpecifier::SArg:
  838. case ConversionSpecifier::ZArg:
  839. return Target.getTriple().isOSMSVCRT();
  840. default:
  841. return false;
  842. }
  843. }
  844. llvm_unreachable("Invalid LengthModifier Kind!");
  845. }
  846. bool FormatSpecifier::hasStandardLengthModifier() const {
  847. switch (LM.getKind()) {
  848. case LengthModifier::None:
  849. case LengthModifier::AsChar:
  850. case LengthModifier::AsShort:
  851. case LengthModifier::AsLong:
  852. case LengthModifier::AsLongLong:
  853. case LengthModifier::AsIntMax:
  854. case LengthModifier::AsSizeT:
  855. case LengthModifier::AsPtrDiff:
  856. case LengthModifier::AsLongDouble:
  857. return true;
  858. case LengthModifier::AsAllocate:
  859. case LengthModifier::AsMAllocate:
  860. case LengthModifier::AsQuad:
  861. case LengthModifier::AsInt32:
  862. case LengthModifier::AsInt3264:
  863. case LengthModifier::AsInt64:
  864. case LengthModifier::AsWide:
  865. case LengthModifier::AsShortLong: // ???
  866. return false;
  867. }
  868. llvm_unreachable("Invalid LengthModifier Kind!");
  869. }
  870. bool FormatSpecifier::hasStandardConversionSpecifier(
  871. const LangOptions &LangOpt) const {
  872. switch (CS.getKind()) {
  873. case ConversionSpecifier::bArg:
  874. case ConversionSpecifier::BArg:
  875. case ConversionSpecifier::cArg:
  876. case ConversionSpecifier::dArg:
  877. case ConversionSpecifier::iArg:
  878. case ConversionSpecifier::oArg:
  879. case ConversionSpecifier::uArg:
  880. case ConversionSpecifier::xArg:
  881. case ConversionSpecifier::XArg:
  882. case ConversionSpecifier::fArg:
  883. case ConversionSpecifier::FArg:
  884. case ConversionSpecifier::eArg:
  885. case ConversionSpecifier::EArg:
  886. case ConversionSpecifier::gArg:
  887. case ConversionSpecifier::GArg:
  888. case ConversionSpecifier::aArg:
  889. case ConversionSpecifier::AArg:
  890. case ConversionSpecifier::sArg:
  891. case ConversionSpecifier::pArg:
  892. case ConversionSpecifier::nArg:
  893. case ConversionSpecifier::ObjCObjArg:
  894. case ConversionSpecifier::ScanListArg:
  895. case ConversionSpecifier::PercentArg:
  896. case ConversionSpecifier::PArg:
  897. return true;
  898. case ConversionSpecifier::CArg:
  899. case ConversionSpecifier::SArg:
  900. return LangOpt.ObjC;
  901. case ConversionSpecifier::InvalidSpecifier:
  902. case ConversionSpecifier::FreeBSDbArg:
  903. case ConversionSpecifier::FreeBSDDArg:
  904. case ConversionSpecifier::FreeBSDrArg:
  905. case ConversionSpecifier::FreeBSDyArg:
  906. case ConversionSpecifier::PrintErrno:
  907. case ConversionSpecifier::DArg:
  908. case ConversionSpecifier::OArg:
  909. case ConversionSpecifier::UArg:
  910. case ConversionSpecifier::ZArg:
  911. return false;
  912. }
  913. llvm_unreachable("Invalid ConversionSpecifier Kind!");
  914. }
  915. bool FormatSpecifier::hasStandardLengthConversionCombination() const {
  916. if (LM.getKind() == LengthModifier::AsLongDouble) {
  917. switch(CS.getKind()) {
  918. case ConversionSpecifier::dArg:
  919. case ConversionSpecifier::iArg:
  920. case ConversionSpecifier::oArg:
  921. case ConversionSpecifier::uArg:
  922. case ConversionSpecifier::xArg:
  923. case ConversionSpecifier::XArg:
  924. return false;
  925. default:
  926. return true;
  927. }
  928. }
  929. return true;
  930. }
  931. std::optional<LengthModifier>
  932. FormatSpecifier::getCorrectedLengthModifier() const {
  933. if (CS.isAnyIntArg() || CS.getKind() == ConversionSpecifier::nArg) {
  934. if (LM.getKind() == LengthModifier::AsLongDouble ||
  935. LM.getKind() == LengthModifier::AsQuad) {
  936. LengthModifier FixedLM(LM);
  937. FixedLM.setKind(LengthModifier::AsLongLong);
  938. return FixedLM;
  939. }
  940. }
  941. return std::nullopt;
  942. }
  943. bool FormatSpecifier::namedTypeToLengthModifier(QualType QT,
  944. LengthModifier &LM) {
  945. for (/**/; const auto *TT = QT->getAs<TypedefType>();
  946. QT = TT->getDecl()->getUnderlyingType()) {
  947. const TypedefNameDecl *Typedef = TT->getDecl();
  948. const IdentifierInfo *Identifier = Typedef->getIdentifier();
  949. if (Identifier->getName() == "size_t") {
  950. LM.setKind(LengthModifier::AsSizeT);
  951. return true;
  952. } else if (Identifier->getName() == "ssize_t") {
  953. // Not C99, but common in Unix.
  954. LM.setKind(LengthModifier::AsSizeT);
  955. return true;
  956. } else if (Identifier->getName() == "intmax_t") {
  957. LM.setKind(LengthModifier::AsIntMax);
  958. return true;
  959. } else if (Identifier->getName() == "uintmax_t") {
  960. LM.setKind(LengthModifier::AsIntMax);
  961. return true;
  962. } else if (Identifier->getName() == "ptrdiff_t") {
  963. LM.setKind(LengthModifier::AsPtrDiff);
  964. return true;
  965. }
  966. }
  967. return false;
  968. }