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