clang  14.0.0git
FormatString.cpp
Go to the documentation of this file.
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 
14 #include "FormatStringParsing.h"
16 #include "clang/Basic/TargetInfo.h"
17 #include "llvm/Support/ConvertUTF.h"
18 
26 using namespace clang;
27 
28 // Key function to FormatStringHandler.
29 FormatStringHandler::~FormatStringHandler() {}
30 
31 //===----------------------------------------------------------------------===//
32 // Functions for parsing format strings components in both printf and
33 // scanf format strings.
34 //===----------------------------------------------------------------------===//
35 
37 clang::analyze_format_string::ParseAmount(const char *&Beg, const char *E) {
38  const char *I = Beg;
39  UpdateOnReturn <const char*> UpdateBeg(Beg, I);
40 
41  unsigned accumulator = 0;
42  bool hasDigits = false;
43 
44  for ( ; I != E; ++I) {
45  char c = *I;
46  if (c >= '0' && c <= '9') {
47  hasDigits = true;
48  accumulator = (accumulator * 10) + (c - '0');
49  continue;
50  }
51 
52  if (hasDigits)
53  return OptionalAmount(OptionalAmount::Constant, accumulator, Beg, I - Beg,
54  false);
55 
56  break;
57  }
58 
59  return OptionalAmount();
60 }
61 
64  const char *E,
65  unsigned &argIndex) {
66  if (*Beg == '*') {
67  ++Beg;
68  return OptionalAmount(OptionalAmount::Arg, argIndex++, Beg, 0, false);
69  }
70 
71  return ParseAmount(Beg, E);
72 }
73 
76  const char *Start,
77  const char *&Beg,
78  const char *E,
79  PositionContext p) {
80  if (*Beg == '*') {
81  const char *I = Beg + 1;
82  const OptionalAmount &Amt = ParseAmount(I, E);
83 
84  if (Amt.getHowSpecified() == OptionalAmount::NotSpecified) {
85  H.HandleInvalidPosition(Beg, I - Beg, p);
86  return OptionalAmount(false);
87  }
88 
89  if (I == E) {
90  // No more characters left?
91  H.HandleIncompleteSpecifier(Start, E - Start);
92  return OptionalAmount(false);
93  }
94 
95  assert(Amt.getHowSpecified() == OptionalAmount::Constant);
96 
97  if (*I == '$') {
98  // Handle positional arguments
99 
100  // Special case: '*0$', since this is an easy mistake.
101  if (Amt.getConstantAmount() == 0) {
102  H.HandleZeroPosition(Beg, I - Beg + 1);
103  return OptionalAmount(false);
104  }
105 
106  const char *Tmp = Beg;
107  Beg = ++I;
108 
109  return OptionalAmount(OptionalAmount::Arg, Amt.getConstantAmount() - 1,
110  Tmp, 0, true);
111  }
112 
113  H.HandleInvalidPosition(Beg, I - Beg, p);
114  return OptionalAmount(false);
115  }
116 
117  return ParseAmount(Beg, E);
118 }
119 
120 
121 bool
123  FormatSpecifier &CS,
124  const char *Start,
125  const char *&Beg, const char *E,
126  unsigned *argIndex) {
127  // FIXME: Support negative field widths.
128  if (argIndex) {
129  CS.setFieldWidth(ParseNonPositionAmount(Beg, E, *argIndex));
130  }
131  else {
132  const OptionalAmount Amt =
133  ParsePositionAmount(H, Start, Beg, E,
135 
136  if (Amt.isInvalid())
137  return true;
138  CS.setFieldWidth(Amt);
139  }
140  return false;
141 }
142 
143 bool
145  FormatSpecifier &FS,
146  const char *Start,
147  const char *&Beg,
148  const char *E) {
149  const char *I = Beg;
150 
151  const OptionalAmount &Amt = ParseAmount(I, E);
152 
153  if (I == E) {
154  // No more characters left?
155  H.HandleIncompleteSpecifier(Start, E - Start);
156  return true;
157  }
158 
159  if (Amt.getHowSpecified() == OptionalAmount::Constant && *(I++) == '$') {
160  // Warn that positional arguments are non-standard.
161  H.HandlePosition(Start, I - Start);
162 
163  // Special case: '%0$', since this is an easy mistake.
164  if (Amt.getConstantAmount() == 0) {
165  H.HandleZeroPosition(Start, I - Start);
166  return true;
167  }
168 
169  FS.setArgIndex(Amt.getConstantAmount() - 1);
170  FS.setUsesPositionalArg();
171  // Update the caller's pointer if we decided to consume
172  // these characters.
173  Beg = I;
174  return false;
175  }
176 
177  return false;
178 }
179 
180 bool
182  FormatSpecifier &FS,
183  const char *&I,
184  const char *E,
185  const LangOptions &LO) {
186  if (!LO.OpenCL)
187  return false;
188 
189  const char *Start = I;
190  if (*I == 'v') {
191  ++I;
192 
193  if (I == E) {
194  H.HandleIncompleteSpecifier(Start, E - Start);
195  return true;
196  }
197 
198  OptionalAmount NumElts = ParseAmount(I, E);
199  if (NumElts.getHowSpecified() != OptionalAmount::Constant) {
200  H.HandleIncompleteSpecifier(Start, E - Start);
201  return true;
202  }
203 
204  FS.setVectorNumElts(NumElts);
205  }
206 
207  return false;
208 }
209 
210 bool
212  const char *&I,
213  const char *E,
214  const LangOptions &LO,
215  bool IsScanf) {
217  const char *lmPosition = I;
218  switch (*I) {
219  default:
220  return false;
221  case 'h':
222  ++I;
223  if (I != E && *I == 'h') {
224  ++I;
225  lmKind = LengthModifier::AsChar;
226  } else if (I != E && *I == 'l' && LO.OpenCL) {
227  ++I;
228  lmKind = LengthModifier::AsShortLong;
229  } else {
230  lmKind = LengthModifier::AsShort;
231  }
232  break;
233  case 'l':
234  ++I;
235  if (I != E && *I == 'l') {
236  ++I;
237  lmKind = LengthModifier::AsLongLong;
238  } else {
239  lmKind = LengthModifier::AsLong;
240  }
241  break;
242  case 'j': lmKind = LengthModifier::AsIntMax; ++I; break;
243  case 'z': lmKind = LengthModifier::AsSizeT; ++I; break;
244  case 't': lmKind = LengthModifier::AsPtrDiff; ++I; break;
245  case 'L': lmKind = LengthModifier::AsLongDouble; ++I; break;
246  case 'q': lmKind = LengthModifier::AsQuad; ++I; break;
247  case 'a':
248  if (IsScanf && !LO.C99 && !LO.CPlusPlus11) {
249  // For scanf in C90, look at the next character to see if this should
250  // be parsed as the GNU extension 'a' length modifier. If not, this
251  // will be parsed as a conversion specifier.
252  ++I;
253  if (I != E && (*I == 's' || *I == 'S' || *I == '[')) {
254  lmKind = LengthModifier::AsAllocate;
255  break;
256  }
257  --I;
258  }
259  return false;
260  case 'm':
261  if (IsScanf) {
262  lmKind = LengthModifier::AsMAllocate;
263  ++I;
264  break;
265  }
266  return false;
267  // printf: AsInt64, AsInt32, AsInt3264
268  // scanf: AsInt64
269  case 'I':
270  if (I + 1 != E && I + 2 != E) {
271  if (I[1] == '6' && I[2] == '4') {
272  I += 3;
273  lmKind = LengthModifier::AsInt64;
274  break;
275  }
276  if (IsScanf)
277  return false;
278 
279  if (I[1] == '3' && I[2] == '2') {
280  I += 3;
281  lmKind = LengthModifier::AsInt32;
282  break;
283  }
284  }
285  ++I;
286  lmKind = LengthModifier::AsInt3264;
287  break;
288  case 'w':
289  lmKind = LengthModifier::AsWide; ++I; break;
290  }
291  LengthModifier lm(lmPosition, lmKind);
292  FS.setLengthModifier(lm);
293  return true;
294 }
295 
297  const char *SpecifierBegin, const char *FmtStrEnd, unsigned &Len) {
298  if (SpecifierBegin + 1 >= FmtStrEnd)
299  return false;
300 
301  const llvm::UTF8 *SB =
302  reinterpret_cast<const llvm::UTF8 *>(SpecifierBegin + 1);
303  const llvm::UTF8 *SE = reinterpret_cast<const llvm::UTF8 *>(FmtStrEnd);
304  const char FirstByte = *SB;
305 
306  // If the invalid specifier is a multibyte UTF-8 string, return the
307  // total length accordingly so that the conversion specifier can be
308  // properly updated to reflect a complete UTF-8 specifier.
309  unsigned NumBytes = llvm::getNumBytesForUTF8(FirstByte);
310  if (NumBytes == 1)
311  return false;
312  if (SB + NumBytes > SE)
313  return false;
314 
315  Len = NumBytes + 1;
316  return true;
317 }
318 
319 //===----------------------------------------------------------------------===//
320 // Methods on ArgType.
321 //===----------------------------------------------------------------------===//
322 
324 ArgType::matchesType(ASTContext &C, QualType argTy) const {
325  if (Ptr) {
326  // It has to be a pointer.
327  const PointerType *PT = argTy->getAs<PointerType>();
328  if (!PT)
329  return NoMatch;
330 
331  // We cannot write through a const qualified pointer.
332  if (PT->getPointeeType().isConstQualified())
333  return NoMatch;
334 
335  argTy = PT->getPointeeType();
336  }
337 
338  switch (K) {
339  case InvalidTy:
340  llvm_unreachable("ArgType must be valid");
341 
342  case UnknownTy:
343  return Match;
344 
345  case AnyCharTy: {
346  if (const EnumType *ETy = argTy->getAs<EnumType>()) {
347  // If the enum is incomplete we know nothing about the underlying type.
348  // Assume that it's 'int'.
349  if (!ETy->getDecl()->isComplete())
350  return NoMatch;
351  argTy = ETy->getDecl()->getIntegerType();
352  }
353 
354  if (const BuiltinType *BT = argTy->getAs<BuiltinType>())
355  switch (BT->getKind()) {
356  default:
357  break;
358  case BuiltinType::Char_S:
359  case BuiltinType::SChar:
360  case BuiltinType::UChar:
361  case BuiltinType::Char_U:
362  case BuiltinType::Bool:
363  return Match;
364  }
365  return NoMatch;
366  }
367 
368  case SpecificTy: {
369  if (const EnumType *ETy = argTy->getAs<EnumType>()) {
370  // If the enum is incomplete we know nothing about the underlying type.
371  // Assume that it's 'int'.
372  if (!ETy->getDecl()->isComplete())
373  argTy = C.IntTy;
374  else
375  argTy = ETy->getDecl()->getIntegerType();
376  }
377  argTy = C.getCanonicalType(argTy).getUnqualifiedType();
378 
379  if (T == argTy)
380  return Match;
381  // Check for "compatible types".
382  if (const BuiltinType *BT = argTy->getAs<BuiltinType>())
383  switch (BT->getKind()) {
384  default:
385  break;
386  case BuiltinType::Char_S:
387  case BuiltinType::SChar:
388  case BuiltinType::Char_U:
389  case BuiltinType::UChar:
390  case BuiltinType::Bool:
391  if (T == C.UnsignedShortTy || T == C.ShortTy)
392  return NoMatchTypeConfusion;
393  return T == C.UnsignedCharTy || T == C.SignedCharTy ? Match
394  : NoMatch;
395  case BuiltinType::Short:
396  return T == C.UnsignedShortTy ? Match : NoMatch;
397  case BuiltinType::UShort:
398  return T == C.ShortTy ? Match : NoMatch;
399  case BuiltinType::Int:
400  return T == C.UnsignedIntTy ? Match : NoMatch;
401  case BuiltinType::UInt:
402  return T == C.IntTy ? Match : NoMatch;
403  case BuiltinType::Long:
404  return T == C.UnsignedLongTy ? Match : NoMatch;
405  case BuiltinType::ULong:
406  return T == C.LongTy ? Match : NoMatch;
407  case BuiltinType::LongLong:
408  return T == C.UnsignedLongLongTy ? Match : NoMatch;
409  case BuiltinType::ULongLong:
410  return T == C.LongLongTy ? Match : NoMatch;
411  }
412  return NoMatch;
413  }
414 
415  case CStrTy: {
416  const PointerType *PT = argTy->getAs<PointerType>();
417  if (!PT)
418  return NoMatch;
419  QualType pointeeTy = PT->getPointeeType();
420  if (const BuiltinType *BT = pointeeTy->getAs<BuiltinType>())
421  switch (BT->getKind()) {
422  case BuiltinType::Char_U:
423  case BuiltinType::UChar:
424  case BuiltinType::Char_S:
425  case BuiltinType::SChar:
426  return Match;
427  default:
428  break;
429  }
430 
431  return NoMatch;
432  }
433 
434  case WCStrTy: {
435  const PointerType *PT = argTy->getAs<PointerType>();
436  if (!PT)
437  return NoMatch;
438  QualType pointeeTy =
439  C.getCanonicalType(PT->getPointeeType()).getUnqualifiedType();
440  return pointeeTy == C.getWideCharType() ? Match : NoMatch;
441  }
442 
443  case WIntTy: {
444  QualType WInt = C.getCanonicalType(C.getWIntType()).getUnqualifiedType();
445 
446  if (C.getCanonicalType(argTy).getUnqualifiedType() == WInt)
447  return Match;
448 
449  QualType PromoArg = argTy->isPromotableIntegerType()
450  ? C.getPromotedIntegerType(argTy)
451  : argTy;
452  PromoArg = C.getCanonicalType(PromoArg).getUnqualifiedType();
453 
454  // If the promoted argument is the corresponding signed type of the
455  // wint_t type, then it should match.
456  if (PromoArg->hasSignedIntegerRepresentation() &&
457  C.getCorrespondingUnsignedType(PromoArg) == WInt)
458  return Match;
459 
460  return WInt == PromoArg ? Match : NoMatch;
461  }
462 
463  case CPointerTy:
464  if (argTy->isVoidPointerType()) {
465  return Match;
466  } if (argTy->isPointerType() || argTy->isObjCObjectPointerType() ||
467  argTy->isBlockPointerType() || argTy->isNullPtrType()) {
468  return NoMatchPedantic;
469  } else {
470  return NoMatch;
471  }
472 
473  case ObjCPointerTy: {
474  if (argTy->getAs<ObjCObjectPointerType>() ||
475  argTy->getAs<BlockPointerType>())
476  return Match;
477 
478  // Handle implicit toll-free bridging.
479  if (const PointerType *PT = argTy->getAs<PointerType>()) {
480  // Things such as CFTypeRef are really just opaque pointers
481  // to C structs representing CF types that can often be bridged
482  // to Objective-C objects. Since the compiler doesn't know which
483  // structs can be toll-free bridged, we just accept them all.
484  QualType pointee = PT->getPointeeType();
485  if (pointee->getAsStructureType() || pointee->isVoidType())
486  return Match;
487  }
488  return NoMatch;
489  }
490  }
491 
492  llvm_unreachable("Invalid ArgType Kind!");
493 }
494 
495 ArgType ArgType::makeVectorType(ASTContext &C, unsigned NumElts) const {
496  // Check for valid vector element types.
497  if (T.isNull())
498  return ArgType::Invalid();
499 
500  QualType Vec = C.getExtVectorType(T, NumElts);
501  return ArgType(Vec, Name);
502 }
503 
504 QualType ArgType::getRepresentativeType(ASTContext &C) const {
505  QualType Res;
506  switch (K) {
507  case InvalidTy:
508  llvm_unreachable("No representative type for Invalid ArgType");
509  case UnknownTy:
510  llvm_unreachable("No representative type for Unknown ArgType");
511  case AnyCharTy:
512  Res = C.CharTy;
513  break;
514  case SpecificTy:
515  Res = T;
516  break;
517  case CStrTy:
518  Res = C.getPointerType(C.CharTy);
519  break;
520  case WCStrTy:
521  Res = C.getPointerType(C.getWideCharType());
522  break;
523  case ObjCPointerTy:
524  Res = C.ObjCBuiltinIdTy;
525  break;
526  case CPointerTy:
527  Res = C.VoidPtrTy;
528  break;
529  case WIntTy: {
530  Res = C.getWIntType();
531  break;
532  }
533  }
534 
535  if (Ptr)
536  Res = C.getPointerType(Res);
537  return Res;
538 }
539 
540 std::string ArgType::getRepresentativeTypeName(ASTContext &C) const {
541  std::string S = getRepresentativeType(C).getAsString(C.getPrintingPolicy());
542 
543  std::string Alias;
544  if (Name) {
545  // Use a specific name for this type, e.g. "size_t".
546  Alias = Name;
547  if (Ptr) {
548  // If ArgType is actually a pointer to T, append an asterisk.
549  Alias += (Alias[Alias.size()-1] == '*') ? "*" : " *";
550  }
551  // If Alias is the same as the underlying type, e.g. wchar_t, then drop it.
552  if (S == Alias)
553  Alias.clear();
554  }
555 
556  if (!Alias.empty())
557  return std::string("'") + Alias + "' (aka '" + S + "')";
558  return std::string("'") + S + "'";
559 }
560 
561 
562 //===----------------------------------------------------------------------===//
563 // Methods on OptionalAmount.
564 //===----------------------------------------------------------------------===//
565 
566 ArgType
568  return Ctx.IntTy;
569 }
570 
571 //===----------------------------------------------------------------------===//
572 // Methods on LengthModifier.
573 //===----------------------------------------------------------------------===//
574 
575 const char *
577  switch (kind) {
578  case AsChar:
579  return "hh";
580  case AsShort:
581  return "h";
582  case AsShortLong:
583  return "hl";
584  case AsLong: // or AsWideChar
585  return "l";
586  case AsLongLong:
587  return "ll";
588  case AsQuad:
589  return "q";
590  case AsIntMax:
591  return "j";
592  case AsSizeT:
593  return "z";
594  case AsPtrDiff:
595  return "t";
596  case AsInt32:
597  return "I32";
598  case AsInt3264:
599  return "I";
600  case AsInt64:
601  return "I64";
602  case AsLongDouble:
603  return "L";
604  case AsAllocate:
605  return "a";
606  case AsMAllocate:
607  return "m";
608  case AsWide:
609  return "w";
610  case None:
611  return "";
612  }
613  return nullptr;
614 }
615 
616 //===----------------------------------------------------------------------===//
617 // Methods on ConversionSpecifier.
618 //===----------------------------------------------------------------------===//
619 
620 const char *ConversionSpecifier::toString() const {
621  switch (kind) {
622  case dArg: return "d";
623  case DArg: return "D";
624  case iArg: return "i";
625  case oArg: return "o";
626  case OArg: return "O";
627  case uArg: return "u";
628  case UArg: return "U";
629  case xArg: return "x";
630  case XArg: return "X";
631  case fArg: return "f";
632  case FArg: return "F";
633  case eArg: return "e";
634  case EArg: return "E";
635  case gArg: return "g";
636  case GArg: return "G";
637  case aArg: return "a";
638  case AArg: return "A";
639  case cArg: return "c";
640  case sArg: return "s";
641  case pArg: return "p";
642  case PArg:
643  return "P";
644  case nArg: return "n";
645  case PercentArg: return "%";
646  case ScanListArg: return "[";
647  case InvalidSpecifier: return nullptr;
648 
649  // POSIX unicode extensions.
650  case CArg: return "C";
651  case SArg: return "S";
652 
653  // Objective-C specific specifiers.
654  case ObjCObjArg: return "@";
655 
656  // FreeBSD kernel specific specifiers.
657  case FreeBSDbArg: return "b";
658  case FreeBSDDArg: return "D";
659  case FreeBSDrArg: return "r";
660  case FreeBSDyArg: return "y";
661 
662  // GlibC specific specifiers.
663  case PrintErrno: return "m";
664 
665  // MS specific specifiers.
666  case ZArg: return "Z";
667  }
668  return nullptr;
669 }
670 
674 
675  switch (getKind()) {
676  default:
677  return None;
678  case DArg:
679  NewKind = dArg;
680  break;
681  case UArg:
682  NewKind = uArg;
683  break;
684  case OArg:
685  NewKind = oArg;
686  break;
687  }
688 
689  ConversionSpecifier FixedCS(*this);
690  FixedCS.setKind(NewKind);
691  return FixedCS;
692 }
693 
694 //===----------------------------------------------------------------------===//
695 // Methods on OptionalAmount.
696 //===----------------------------------------------------------------------===//
697 
698 void OptionalAmount::toString(raw_ostream &os) const {
699  switch (hs) {
700  case Invalid:
701  case NotSpecified:
702  return;
703  case Arg:
704  if (UsesDotPrefix)
705  os << ".";
706  if (usesPositionalArg())
707  os << "*" << getPositionalArgIndex() << "$";
708  else
709  os << "*";
710  break;
711  case Constant:
712  if (UsesDotPrefix)
713  os << ".";
714  os << amt;
715  break;
716  }
717 }
718 
720  const LangOptions &LO) const {
721  switch (LM.getKind()) {
723  return true;
724 
725  // Handle most integer flags
727  // Length modifier only applies to FP vectors.
728  if (LO.OpenCL && CS.isDoubleArg())
729  return !VectorNumElts.isInvalid();
730 
731  if (Target.getTriple().isOSMSVCRT()) {
732  switch (CS.getKind()) {
738  return true;
739  default:
740  break;
741  }
742  }
743  LLVM_FALLTHROUGH;
750  switch (CS.getKind()) {
761  return true;
764  return Target.getTriple().isOSFreeBSD() || Target.getTriple().isPS4();
765  default:
766  return false;
767  }
768 
770  return LO.OpenCL && !VectorNumElts.isInvalid();
771 
772  // Handle 'l' flag
773  case LengthModifier::AsLong: // or AsWideChar
774  if (CS.isDoubleArg()) {
775  // Invalid for OpenCL FP scalars.
776  if (LO.OpenCL && VectorNumElts.isInvalid())
777  return false;
778  return true;
779  }
780 
781  switch (CS.getKind()) {
796  return true;
799  return Target.getTriple().isOSFreeBSD() || Target.getTriple().isPS4();
800  default:
801  return false;
802  }
803 
805  switch (CS.getKind()) {
814  return true;
815  // GNU libc extension.
822  return !Target.getTriple().isOSDarwin() &&
823  !Target.getTriple().isOSWindows();
824  default:
825  return false;
826  }
827 
829  switch (CS.getKind()) {
833  return true;
834  default:
835  return false;
836  }
837 
839  switch (CS.getKind()) {
845  return true;
846  default:
847  return false;
848  }
852  switch (CS.getKind()) {
859  return Target.getTriple().isOSMSVCRT();
860  default:
861  return false;
862  }
864  switch (CS.getKind()) {
870  return Target.getTriple().isOSMSVCRT();
871  default:
872  return false;
873  }
874  }
875  llvm_unreachable("Invalid LengthModifier Kind!");
876 }
877 
879  switch (LM.getKind()) {
889  return true;
897  case LengthModifier::AsShortLong: // ???
898  return false;
899  }
900  llvm_unreachable("Invalid LengthModifier Kind!");
901 }
902 
904  const LangOptions &LangOpt) const {
905  switch (CS.getKind()) {
928  return true;
931  return LangOpt.ObjC;
942  return false;
943  }
944  llvm_unreachable("Invalid ConversionSpecifier Kind!");
945 }
946 
949  switch(CS.getKind()) {
956  return false;
957  default:
958  return true;
959  }
960  }
961  return true;
962 }
963 
968  LengthModifier FixedLM(LM);
970  return FixedLM;
971  }
972  }
973 
974  return None;
975 }
976 
978  LengthModifier &LM) {
979  assert(isa<TypedefType>(QT) && "Expected a TypedefType");
980  const TypedefNameDecl *Typedef = cast<TypedefType>(QT)->getDecl();
981 
982  for (;;) {
983  const IdentifierInfo *Identifier = Typedef->getIdentifier();
984  if (Identifier->getName() == "size_t") {
986  return true;
987  } else if (Identifier->getName() == "ssize_t") {
988  // Not C99, but common in Unix.
990  return true;
991  } else if (Identifier->getName() == "intmax_t") {
993  return true;
994  } else if (Identifier->getName() == "uintmax_t") {
996  return true;
997  } else if (Identifier->getName() == "ptrdiff_t") {
999  return true;
1000  }
1001 
1002  QualType T = Typedef->getUnderlyingType();
1003  if (!isa<TypedefType>(T))
1004  break;
1005 
1006  Typedef = cast<TypedefType>(T)->getDecl();
1007  }
1008  return false;
1009 }
clang::BuiltinType
This class is used for builtin types like 'int'.
Definition: Type.h:2493
clang::analyze_format_string::FormatSpecifier::setFieldWidth
void setFieldWidth(const OptionalAmount &Amt)
Definition: FormatString.h:448
clang::analyze_format_string::ConversionSpecifier::SArg
@ SArg
Definition: FormatString.h:158
clang::analyze_format_string::ConversionSpecifier::oArg
@ oArg
Definition: FormatString.h:133
clang::analyze_format_string::ConversionSpecifier::cArg
@ cArg
Definition: FormatString.h:126
clang::Type::isBlockPointerType
bool isBlockPointerType() const
Definition: Type.h:6680
clang::analyze_format_string::ConversionSpecifier::ObjCObjArg
@ ObjCObjArg
Definition: FormatString.h:170
clang::analyze_format_string::ConversionSpecifier::isAnyIntArg
bool isAnyIntArg() const
Definition: FormatString.h:231
string
string(SUBSTRING ${CMAKE_CURRENT_BINARY_DIR} 0 ${PATH_LIB_START} PATH_HEAD) string(SUBSTRING $
Definition: CMakeLists.txt:22
clang::Type::isVoidPointerType
bool isVoidPointerType() const
Definition: Type.cpp:589
clang::analyze_format_string::LengthModifier::AsMAllocate
@ AsMAllocate
Definition: FormatString.h:82
clang::analyze_format_string::LengthModifier::AsLongDouble
@ AsLongDouble
Definition: FormatString.h:80
clang::QualType::isConstQualified
bool isConstQualified() const
Determine whether this type is const-qualified.
Definition: Type.h:6483
clang::analyze_format_string::ConversionSpecifier::xArg
@ xArg
Definition: FormatString.h:137
clang::analyze_format_string::FormatStringHandler
Definition: FormatString.h:692
clang::analyze_format_string::FormatSpecifier
Definition: FormatString.h:397
clang::analyze_format_string::FormatSpecifier::namedTypeToLengthModifier
static bool namedTypeToLengthModifier(QualType QT, LengthModifier &LM)
For a TypedefType QT, if it is a named integer type such as size_t, assign the appropriate value to L...
Definition: FormatString.cpp:977
TargetInfo.h
clang::MultiVersionKind::Target
@ Target
clang::QualType
A (possibly-)qualified type.
Definition: Type.h:673
clang::analyze_format_string::ConversionSpecifier::isDoubleArg
bool isDoubleArg() const
Definition: FormatString.h:232
clang::analyze_format_string::OptionalAmount::getConstantAmount
unsigned getConstantAmount() const
Definition: FormatString.h:359
clang::analyze_format_string::ConversionSpecifier::sArg
@ sArg
Definition: FormatString.h:153
clang::TargetInfo
Exposes information about the current target.
Definition: TargetInfo.h:189
clang::analyze_format_string::FormatSpecifier::CS
ConversionSpecifier CS
Definition: FormatString.h:401
clang::analyze_format_string::OptionalAmount::usesPositionalArg
bool usesPositionalArg() const
Definition: FormatString.h:378
clang::analyze_format_string::FormatStringHandler::HandleInvalidPosition
virtual void HandleInvalidPosition(const char *startPos, unsigned posLen, PositionContext p)
Definition: FormatString.h:701
clang::analyze_format_string::LengthModifier::AsInt3264
@ AsInt3264
Definition: FormatString.h:78
llvm::Optional
Definition: LLVM.h:40
clang::Type::isVoidType
bool isVoidType() const
Definition: Type.h:6955
Identifier
StringRef Identifier
Definition: Format.cpp:2341
clang::analyze_format_string::ParsePositionAmount
OptionalAmount ParsePositionAmount(FormatStringHandler &H, const char *Start, const char *&Beg, const char *E, PositionContext p)
Definition: FormatString.cpp:75
clang::analyze_format_string::FormatStringHandler::HandleZeroPosition
virtual void HandleZeroPosition(const char *startPos, unsigned posLen)
Definition: FormatString.h:704
clang::analyze_format_string::ConversionSpecifier::iArg
@ iArg
Definition: FormatString.h:129
clang::analyze_format_string::ConversionSpecifier
Definition: FormatString.h:121
clang::analyze_format_string::ArgType::MatchKind
MatchKind
How well a given conversion specifier matches its argument.
Definition: FormatString.h:255
clang::analyze_format_string::ConversionSpecifier::FArg
@ FArg
Definition: FormatString.h:143
clang::analyze_format_string::ConversionSpecifier::fArg
@ fArg
Definition: FormatString.h:142
clang::analyze_format_string::FormatSpecifier::hasValidLengthModifier
bool hasValidLengthModifier(const TargetInfo &Target, const LangOptions &LO) const
Definition: FormatString.cpp:719
clang::Type::isPromotableIntegerType
bool isPromotableIntegerType() const
More type predicates useful for type checking/promotion.
Definition: Type.cpp:2744
clang::analyze_format_string::ConversionSpecifier::toString
const char * toString() const
Definition: FormatString.cpp:620
clang::analyze_format_string::LengthModifier::getKind
Kind getKind() const
Definition: FormatString.h:111
clang::analyze_format_string::OptionalAmount::getPositionalArgIndex
unsigned getPositionalArgIndex() const
Definition: FormatString.h:379
clang::Type::hasSignedIntegerRepresentation
bool hasSignedIntegerRepresentation() const
Determine whether this type has an signed integer representation of some sort, e.g....
Definition: Type.cpp:2050
clang::analyze_format_string::ConversionSpecifier::getKind
Kind getKind() const
Definition: FormatString.h:221
clang::analyze_format_string::ConversionSpecifier::FreeBSDDArg
@ FreeBSDDArg
Definition: FormatString.h:176
clang::Type::getAsStructureType
const RecordType * getAsStructureType() const
Definition: Type.cpp:641
clang::analyze_format_string::LengthModifier::setKind
void setKind(Kind k)
Definition: FormatString.h:112
clang::analyze_format_string::OptionalAmount
Definition: FormatString.h:325
clang::analyze_format_string::OptionalAmount::Constant
@ Constant
Definition: FormatString.h:327
clang::analyze_format_string::OptionalAmount::getArgType
ArgType getArgType(ASTContext &Ctx) const
Definition: FormatString.cpp:567
clang::analyze_format_string::OptionalAmount::Arg
@ Arg
Definition: FormatString.h:327
clang::analyze_format_string::ConversionSpecifier::nArg
@ nArg
Definition: FormatString.h:155
clang::analyze_format_string::OptionalAmount::toString
void toString(raw_ostream &os) const
Definition: FormatString.cpp:698
clang::analyze_format_string::ConversionSpecifier::gArg
@ gArg
Definition: FormatString.h:146
clang::analyze_format_string::PositionContext
PositionContext
Definition: FormatString.h:690
clang::Type::isNullPtrType
bool isNullPtrType() const
Definition: Type.h:6980
clang::XRayInstrKind::None
constexpr XRayInstrMask None
Definition: XRayInstr.h:38
clang::analyze_format_string::ConversionSpecifier::DArg
@ DArg
Definition: FormatString.h:128
clang::ASTContext
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
Definition: ASTContext.h:212
LangOptions.h
clang::Type::getAs
const T * getAs() const
Member-template getAs<specific type>'.
Definition: Type.h:7161
clang::analyze_format_string::ParseLengthModifier
bool ParseLengthModifier(FormatSpecifier &FS, const char *&Beg, const char *E, const LangOptions &LO, bool IsScanf=false)
Returns true if a LengthModifier was parsed and installed in the FormatSpecifier& argument,...
Definition: FormatString.cpp:211
clang::analyze_format_string::ConversionSpecifier::FreeBSDyArg
@ FreeBSDyArg
Definition: FormatString.h:178
FormatStringParsing.h
clang::analyze_format_string::ConversionSpecifier::dArg
@ dArg
Definition: FormatString.h:127
clang::analyze_format_string::FieldWidthPos
@ FieldWidthPos
Definition: FormatString.h:690
clang::TypedefNameDecl::getUnderlyingType
QualType getUnderlyingType() const
Definition: Decl.h:3235
clang::analyze_format_string::ParseVectorModifier
bool ParseVectorModifier(FormatStringHandler &H, FormatSpecifier &FS, const char *&Beg, const char *E, const LangOptions &LO)
Definition: FormatString.cpp:181
clang::analyze_format_string::LengthModifier::AsWide
@ AsWide
Definition: FormatString.h:83
clang::analyze_format_string::ConversionSpecifier::ScanListArg
@ ScanListArg
Definition: FormatString.h:187
clang::Type::getPointeeType
QualType getPointeeType() const
If this is a pointer, ObjC object pointer, or block pointer, this returns the respective pointee.
Definition: Type.cpp:625
clang::analyze_format_string::ConversionSpecifier::kind
Kind kind
Definition: FormatString.h:246
clang::analyze_format_string::ConversionSpecifier::uArg
@ uArg
Definition: FormatString.h:135
clang::analyze_format_string::LengthModifier::AsLongLong
@ AsLongLong
Definition: FormatString.h:72
clang::analyze_format_string::LengthModifier::AsQuad
@ AsQuad
Definition: FormatString.h:73
clang::BlockPointerType
Pointer to a block type.
Definition: Type.h:2720
clang::analyze_format_string::LengthModifier::AsInt32
@ AsInt32
Definition: FormatString.h:77
clang::analyze_format_string::LengthModifier::AsIntMax
@ AsIntMax
Definition: FormatString.h:74
clang::analyze_format_string::LengthModifier::AsShort
@ AsShort
Definition: FormatString.h:69
clang::analyze_format_string::FormatSpecifier::hasStandardConversionSpecifier
bool hasStandardConversionSpecifier(const LangOptions &LangOpt) const
Definition: FormatString.cpp:903
clang::Type::isObjCObjectPointerType
bool isObjCObjectPointerType() const
Definition: Type.h:6794
clang::analyze_format_string::OptionalAmount::Invalid
@ Invalid
Definition: FormatString.h:327
clang::analyze_format_string::FormatSpecifier::hasStandardLengthConversionCombination
bool hasStandardLengthConversionCombination() const
Definition: FormatString.cpp:947
clang::analyze_format_string::ConversionSpecifier::Kind
Kind
Definition: FormatString.h:123
clang::analyze_format_string::ParseNonPositionAmount
OptionalAmount ParseNonPositionAmount(const char *&Beg, const char *E, unsigned &argIndex)
Definition: FormatString.cpp:63
clang::ObjCObjectPointerType
Represents a pointer to an Objective C object.
Definition: Type.h:6072
clang::analyze_format_string::LengthModifier::Kind
Kind
Definition: FormatString.h:66
clang::analyze_format_string::LengthModifier::AsSizeT
@ AsSizeT
Definition: FormatString.h:75
clang::analyze_format_string::ConversionSpecifier::XArg
@ XArg
Definition: FormatString.h:138
clang::Type::isPointerType
bool isPointerType() const
Definition: Type.h:6672
clang::analyze_format_string::ParseFieldWidth
bool ParseFieldWidth(FormatStringHandler &H, FormatSpecifier &CS, const char *Start, const char *&Beg, const char *E, unsigned *argIndex)
Definition: FormatString.cpp:122
clang::analyze_format_string::LengthModifier::toString
const char * toString() const
Definition: FormatString.cpp:576
clang::NamedDecl::getIdentifier
IdentifierInfo * getIdentifier() const
Get the identifier that names this declaration, if there is one.
Definition: Decl.h:270
clang::ASTContext::IntTy
CanQualType IntTy
Definition: ASTContext.h:1084
clang::analyze_format_string::ConversionSpecifier::GArg
@ GArg
Definition: FormatString.h:147
clang::analyze_format_string::OptionalAmount::getHowSpecified
HowSpecified getHowSpecified() const
Definition: FormatString.h:349
clang::analyze_format_string::ConversionSpecifier::PrintErrno
@ PrintErrno
Definition: FormatString.h:181
clang::analyze_format_string::ConversionSpecifier::PercentArg
@ PercentArg
Definition: FormatString.h:156
clang::analyze_format_string::LengthModifier::None
@ None
Definition: FormatString.h:67
clang::analyze_format_string::ConversionSpecifier::aArg
@ aArg
Definition: FormatString.h:148
clang::IdentifierInfo
One of these records is kept for each identifier that is lexed.
Definition: IdentifierTable.h:84
clang::analyze_format_string::FormatSpecifier::LM
LengthModifier LM
Definition: FormatString.h:399
clang::analyze_format_string::ParseArgPosition
bool ParseArgPosition(FormatStringHandler &H, FormatSpecifier &CS, const char *Start, const char *&Beg, const char *E)
Definition: FormatString.cpp:144
clang::LangOptions
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
Definition: LangOptions.h:58
clang::analyze_format_string::FormatStringHandler::HandlePosition
virtual void HandlePosition(const char *startPos, unsigned posLen)
Definition: FormatString.h:699
clang::analyze_format_string::ConversionSpecifier::FreeBSDrArg
@ FreeBSDrArg
Definition: FormatString.h:177
clang::analyze_format_string::ConversionSpecifier::OArg
@ OArg
Definition: FormatString.h:134
clang::UpdateOnReturn
Definition: FormatStringParsing.h:26
clang::analyze_format_string::ConversionSpecifier::PArg
@ PArg
Definition: FormatString.h:163
clang::PointerType
PointerType - C99 6.7.5.1 - Pointer Declarators.
Definition: Type.h:2640
clang::analyze_format_string::FormatStringHandler::HandleIncompleteSpecifier
virtual void HandleIncompleteSpecifier(const char *startSpecifier, unsigned specifierLen)
Definition: FormatString.h:706
clang::analyze_format_string::OptionalAmount::isInvalid
bool isInvalid() const
Definition: FormatString.h:345
clang::analyze_format_string::ConversionSpecifier::setKind
void setKind(Kind k)
Definition: FormatString.h:222
clang
Definition: CalledOnceCheck.h:17
clang::analyze_format_string::ArgType
Definition: FormatString.h:249
clang::analyze_format_string::ConversionSpecifier::InvalidSpecifier
@ InvalidSpecifier
Definition: FormatString.h:124
clang::analyze_format_string::ConversionSpecifier::CArg
@ CArg
Definition: FormatString.h:157
clang::analyze_format_string::LengthModifier::AsAllocate
@ AsAllocate
Definition: FormatString.h:81
clang::analyze_format_string::FormatSpecifier::VectorNumElts
OptionalAmount VectorNumElts
Definition: FormatString.h:402
clang::analyze_format_string::FormatSpecifier::getCorrectedLengthModifier
Optional< LengthModifier > getCorrectedLengthModifier() const
Definition: FormatString.cpp:964
clang::analyze_format_string::ConversionSpecifier::ZArg
@ ZArg
Definition: FormatString.h:167
clang::analyze_format_string::ConversionSpecifier::AArg
@ AArg
Definition: FormatString.h:149
clang::analyze_format_string::LengthModifier::AsChar
@ AsChar
Definition: FormatString.h:68
clang::analyze_format_string::ConversionSpecifier::pArg
@ pArg
Definition: FormatString.h:154
clang::analyze_format_string::ConversionSpecifier::UArg
@ UArg
Definition: FormatString.h:136
clang::TypedefNameDecl
Base class for declarations which introduce a typedef-name.
Definition: Decl.h:3180
clang::analyze_format_string::ParseUTF8InvalidSpecifier
bool ParseUTF8InvalidSpecifier(const char *SpecifierBegin, const char *FmtStrEnd, unsigned &Len)
Returns true if the invalid specifier in SpecifierBegin is a UTF-8 string; check that it won't go fur...
Definition: FormatString.cpp:296
clang::analyze_format_string::FormatSpecifier::hasStandardLengthModifier
bool hasStandardLengthModifier() const
Definition: FormatString.cpp:878
c
__device__ __2f16 float c
Definition: __clang_hip_libdevice_declares.h:315
clang::PointerType::getPointeeType
QualType getPointeeType() const
Definition: Type.h:2650
clang::analyze_format_string::ConversionSpecifier::eArg
@ eArg
Definition: FormatString.h:144
clang::analyze_format_string::OptionalAmount::NotSpecified
@ NotSpecified
Definition: FormatString.h:327
clang::analyze_format_string::ConversionSpecifier::FreeBSDbArg
@ FreeBSDbArg
Definition: FormatString.h:175
clang::analyze_format_string::ConversionSpecifier::getStandardSpecifier
Optional< ConversionSpecifier > getStandardSpecifier() const
Definition: FormatString.cpp:672
clang::analyze_format_string::LengthModifier::AsShortLong
@ AsShortLong
Definition: FormatString.h:70
clang::EnumType
A helper class that allows the use of isa/cast/dyncast to detect TagType objects of enums.
Definition: Type.h:4639
clang::analyze_format_string::ParseAmount
OptionalAmount ParseAmount(const char *&Beg, const char *E)
Definition: FormatString.cpp:37
clang::analyze_format_string::LengthModifier
Represents the length modifier in a format string in scanf/printf.
Definition: FormatString.h:64
clang::analyze_format_string::ConversionSpecifier::EArg
@ EArg
Definition: FormatString.h:145
clang::analyze_format_string::LengthModifier::AsLong
@ AsLong
Definition: FormatString.h:71
clang::diag::kind
unsigned kind
All of the diagnostics that can be emitted by the frontend.
Definition: DiagnosticIDs.h:62
clang::analyze_format_string::LengthModifier::AsPtrDiff
@ AsPtrDiff
Definition: FormatString.h:76
clang::analyze_format_string::LengthModifier::AsInt64
@ AsInt64
Definition: FormatString.h:79