clang  10.0.0svn
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);
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::Void:
423  case BuiltinType::Char_U:
424  case BuiltinType::UChar:
425  case BuiltinType::Char_S:
426  case BuiltinType::SChar:
427  return Match;
428  default:
429  break;
430  }
431 
432  return NoMatch;
433  }
434 
435  case WCStrTy: {
436  const PointerType *PT = argTy->getAs<PointerType>();
437  if (!PT)
438  return NoMatch;
439  QualType pointeeTy =
440  C.getCanonicalType(PT->getPointeeType()).getUnqualifiedType();
441  return pointeeTy == C.getWideCharType() ? Match : NoMatch;
442  }
443 
444  case WIntTy: {
445  QualType WInt = C.getCanonicalType(C.getWIntType()).getUnqualifiedType();
446 
447  if (C.getCanonicalType(argTy).getUnqualifiedType() == WInt)
448  return Match;
449 
450  QualType PromoArg = argTy->isPromotableIntegerType()
451  ? C.getPromotedIntegerType(argTy)
452  : argTy;
453  PromoArg = C.getCanonicalType(PromoArg).getUnqualifiedType();
454 
455  // If the promoted argument is the corresponding signed type of the
456  // wint_t type, then it should match.
457  if (PromoArg->hasSignedIntegerRepresentation() &&
458  C.getCorrespondingUnsignedType(PromoArg) == WInt)
459  return Match;
460 
461  return WInt == PromoArg ? Match : NoMatch;
462  }
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 
474  case ObjCPointerTy: {
475  if (argTy->getAs<ObjCObjectPointerType>() ||
476  argTy->getAs<BlockPointerType>())
477  return Match;
478 
479  // Handle implicit toll-free bridging.
480  if (const PointerType *PT = argTy->getAs<PointerType>()) {
481  // Things such as CFTypeRef are really just opaque pointers
482  // to C structs representing CF types that can often be bridged
483  // to Objective-C objects. Since the compiler doesn't know which
484  // structs can be toll-free bridged, we just accept them all.
485  QualType pointee = PT->getPointeeType();
486  if (pointee->getAsStructureType() || pointee->isVoidType())
487  return Match;
488  }
489  return NoMatch;
490  }
491  }
492 
493  llvm_unreachable("Invalid ArgType Kind!");
494 }
495 
496 ArgType ArgType::makeVectorType(ASTContext &C, unsigned NumElts) const {
497  // Check for valid vector element types.
498  if (T.isNull())
499  return ArgType::Invalid();
500 
501  QualType Vec = C.getExtVectorType(T, NumElts);
502  return ArgType(Vec, Name);
503 }
504 
505 QualType ArgType::getRepresentativeType(ASTContext &C) const {
506  QualType Res;
507  switch (K) {
508  case InvalidTy:
509  llvm_unreachable("No representative type for Invalid ArgType");
510  case UnknownTy:
511  llvm_unreachable("No representative type for Unknown ArgType");
512  case AnyCharTy:
513  Res = C.CharTy;
514  break;
515  case SpecificTy:
516  Res = T;
517  break;
518  case CStrTy:
519  Res = C.getPointerType(C.CharTy);
520  break;
521  case WCStrTy:
522  Res = C.getPointerType(C.getWideCharType());
523  break;
524  case ObjCPointerTy:
525  Res = C.ObjCBuiltinIdTy;
526  break;
527  case CPointerTy:
528  Res = C.VoidPtrTy;
529  break;
530  case WIntTy: {
531  Res = C.getWIntType();
532  break;
533  }
534  }
535 
536  if (Ptr)
537  Res = C.getPointerType(Res);
538  return Res;
539 }
540 
541 std::string ArgType::getRepresentativeTypeName(ASTContext &C) const {
542  std::string S = getRepresentativeType(C).getAsString();
543 
544  std::string Alias;
545  if (Name) {
546  // Use a specific name for this type, e.g. "size_t".
547  Alias = Name;
548  if (Ptr) {
549  // If ArgType is actually a pointer to T, append an asterisk.
550  Alias += (Alias[Alias.size()-1] == '*') ? "*" : " *";
551  }
552  // If Alias is the same as the underlying type, e.g. wchar_t, then drop it.
553  if (S == Alias)
554  Alias.clear();
555  }
556 
557  if (!Alias.empty())
558  return std::string("'") + Alias + "' (aka '" + S + "')";
559  return std::string("'") + S + "'";
560 }
561 
562 
563 //===----------------------------------------------------------------------===//
564 // Methods on OptionalAmount.
565 //===----------------------------------------------------------------------===//
566 
567 ArgType
569  return Ctx.IntTy;
570 }
571 
572 //===----------------------------------------------------------------------===//
573 // Methods on LengthModifier.
574 //===----------------------------------------------------------------------===//
575 
576 const char *
578  switch (kind) {
579  case AsChar:
580  return "hh";
581  case AsShort:
582  return "h";
583  case AsShortLong:
584  return "hl";
585  case AsLong: // or AsWideChar
586  return "l";
587  case AsLongLong:
588  return "ll";
589  case AsQuad:
590  return "q";
591  case AsIntMax:
592  return "j";
593  case AsSizeT:
594  return "z";
595  case AsPtrDiff:
596  return "t";
597  case AsInt32:
598  return "I32";
599  case AsInt3264:
600  return "I";
601  case AsInt64:
602  return "I64";
603  case AsLongDouble:
604  return "L";
605  case AsAllocate:
606  return "a";
607  case AsMAllocate:
608  return "m";
609  case AsWide:
610  return "w";
611  case None:
612  return "";
613  }
614  return nullptr;
615 }
616 
617 //===----------------------------------------------------------------------===//
618 // Methods on ConversionSpecifier.
619 //===----------------------------------------------------------------------===//
620 
621 const char *ConversionSpecifier::toString() const {
622  switch (kind) {
623  case dArg: return "d";
624  case DArg: return "D";
625  case iArg: return "i";
626  case oArg: return "o";
627  case OArg: return "O";
628  case uArg: return "u";
629  case UArg: return "U";
630  case xArg: return "x";
631  case XArg: return "X";
632  case fArg: return "f";
633  case FArg: return "F";
634  case eArg: return "e";
635  case EArg: return "E";
636  case gArg: return "g";
637  case GArg: return "G";
638  case aArg: return "a";
639  case AArg: return "A";
640  case cArg: return "c";
641  case sArg: return "s";
642  case pArg: return "p";
643  case PArg:
644  return "P";
645  case nArg: return "n";
646  case PercentArg: return "%";
647  case ScanListArg: return "[";
648  case InvalidSpecifier: return nullptr;
649 
650  // POSIX unicode extensions.
651  case CArg: return "C";
652  case SArg: return "S";
653 
654  // Objective-C specific specifiers.
655  case ObjCObjArg: return "@";
656 
657  // FreeBSD kernel specific specifiers.
658  case FreeBSDbArg: return "b";
659  case FreeBSDDArg: return "D";
660  case FreeBSDrArg: return "r";
661  case FreeBSDyArg: return "y";
662 
663  // GlibC specific specifiers.
664  case PrintErrno: return "m";
665 
666  // MS specific specifiers.
667  case ZArg: return "Z";
668  }
669  return nullptr;
670 }
671 
675 
676  switch (getKind()) {
677  default:
678  return None;
679  case DArg:
680  NewKind = dArg;
681  break;
682  case UArg:
683  NewKind = uArg;
684  break;
685  case OArg:
686  NewKind = oArg;
687  break;
688  }
689 
690  ConversionSpecifier FixedCS(*this);
691  FixedCS.setKind(NewKind);
692  return FixedCS;
693 }
694 
695 //===----------------------------------------------------------------------===//
696 // Methods on OptionalAmount.
697 //===----------------------------------------------------------------------===//
698 
699 void OptionalAmount::toString(raw_ostream &os) const {
700  switch (hs) {
701  case Invalid:
702  case NotSpecified:
703  return;
704  case Arg:
705  if (UsesDotPrefix)
706  os << ".";
707  if (usesPositionalArg())
708  os << "*" << getPositionalArgIndex() << "$";
709  else
710  os << "*";
711  break;
712  case Constant:
713  if (UsesDotPrefix)
714  os << ".";
715  os << amt;
716  break;
717  }
718 }
719 
721  const LangOptions &LO) const {
722  switch (LM.getKind()) {
724  return true;
725 
726  // Handle most integer flags
728  // Length modifier only applies to FP vectors.
729  if (LO.OpenCL && CS.isDoubleArg())
730  return !VectorNumElts.isInvalid();
731 
732  if (Target.getTriple().isOSMSVCRT()) {
733  switch (CS.getKind()) {
739  return true;
740  default:
741  break;
742  }
743  }
744  LLVM_FALLTHROUGH;
751  switch (CS.getKind()) {
762  return true;
765  return Target.getTriple().isOSFreeBSD() || Target.getTriple().isPS4();
766  default:
767  return false;
768  }
769 
771  return LO.OpenCL && !VectorNumElts.isInvalid();
772 
773  // Handle 'l' flag
774  case LengthModifier::AsLong: // or AsWideChar
775  if (CS.isDoubleArg()) {
776  // Invalid for OpenCL FP scalars.
777  if (LO.OpenCL && VectorNumElts.isInvalid())
778  return false;
779  return true;
780  }
781 
782  switch (CS.getKind()) {
797  return true;
800  return Target.getTriple().isOSFreeBSD() || Target.getTriple().isPS4();
801  default:
802  return false;
803  }
804 
806  switch (CS.getKind()) {
815  return true;
816  // GNU libc extension.
823  return !Target.getTriple().isOSDarwin() &&
824  !Target.getTriple().isOSWindows();
825  default:
826  return false;
827  }
828 
830  switch (CS.getKind()) {
834  return true;
835  default:
836  return false;
837  }
838 
840  switch (CS.getKind()) {
846  return true;
847  default:
848  return false;
849  }
853  switch (CS.getKind()) {
860  return Target.getTriple().isOSMSVCRT();
861  default:
862  return false;
863  }
865  switch (CS.getKind()) {
871  return Target.getTriple().isOSMSVCRT();
872  default:
873  return false;
874  }
875  }
876  llvm_unreachable("Invalid LengthModifier Kind!");
877 }
878 
880  switch (LM.getKind()) {
890  return true;
898  case LengthModifier::AsShortLong: // ???
899  return false;
900  }
901  llvm_unreachable("Invalid LengthModifier Kind!");
902 }
903 
905  const LangOptions &LangOpt) const {
906  switch (CS.getKind()) {
929  return true;
932  return LangOpt.ObjC;
943  return false;
944  }
945  llvm_unreachable("Invalid ConversionSpecifier Kind!");
946 }
947 
949  if (LM.getKind() == LengthModifier::AsLongDouble) {
950  switch(CS.getKind()) {
957  return false;
958  default:
959  return true;
960  }
961  }
962  return true;
963 }
964 
966  if (CS.isAnyIntArg() || CS.getKind() == ConversionSpecifier::nArg) {
967  if (LM.getKind() == LengthModifier::AsLongDouble ||
968  LM.getKind() == LengthModifier::AsQuad) {
969  LengthModifier FixedLM(LM);
971  return FixedLM;
972  }
973  }
974 
975  return None;
976 }
977 
979  LengthModifier &LM) {
980  assert(isa<TypedefType>(QT) && "Expected a TypedefType");
981  const TypedefNameDecl *Typedef = cast<TypedefType>(QT)->getDecl();
982 
983  for (;;) {
984  const IdentifierInfo *Identifier = Typedef->getIdentifier();
985  if (Identifier->getName() == "size_t") {
987  return true;
988  } else if (Identifier->getName() == "ssize_t") {
989  // Not C99, but common in Unix.
991  return true;
992  } else if (Identifier->getName() == "intmax_t") {
994  return true;
995  } else if (Identifier->getName() == "uintmax_t") {
997  return true;
998  } else if (Identifier->getName() == "ptrdiff_t") {
1000  return true;
1001  }
1002 
1003  QualType T = Typedef->getUnderlyingType();
1004  if (!isa<TypedefType>(T))
1005  break;
1006 
1007  Typedef = cast<TypedefType>(T)->getDecl();
1008  }
1009  return false;
1010 }
virtual void HandlePosition(const char *startPos, unsigned posLen)
Definition: FormatString.h:699
CanQualType LongLongTy
Definition: ASTContext.h:1024
StringRef Identifier
Definition: Format.cpp:1815
PointerType - C99 6.7.5.1 - Pointer Declarators.
Definition: Type.h:2585
CanQualType VoidPtrTy
Definition: ASTContext.h:1043
QualType getPointeeType() const
Definition: Type.h:2598
A (possibly-)qualified type.
Definition: Type.h:643
bool isBlockPointerType() const
Definition: Type.h:6399
bool hasValidLengthModifier(const TargetInfo &Target, const LangOptions &LO) const
QualType getPointeeType() const
If this is a pointer, ObjC object pointer, or block pointer, this returns the respective pointee...
Definition: Type.cpp:557
const llvm::Triple & getTriple() const
Returns the target triple of the primary target.
Definition: TargetInfo.h:991
bool ParseVectorModifier(FormatStringHandler &H, FormatSpecifier &FS, const char *&Beg, const char *E, const LangOptions &LO)
virtual void HandleZeroPosition(const char *startPos, unsigned posLen)
Definition: FormatString.h:704
const RecordType * getAsStructureType() const
Definition: Type.cpp:573
bool ParseArgPosition(FormatStringHandler &H, FormatSpecifier &CS, const char *Start, const char *&Beg, const char *E)
CanQualType LongTy
Definition: ASTContext.h:1024
CanQual< T > getUnqualifiedType() const
Retrieve the unqualified form of this type.
QualType getCorrespondingUnsignedType(QualType T) const
const T * getAs() const
Member-template getAs<specific type>&#39;.
Definition: Type.h:6858
MatchKind
How well a given conversion specifier matches its argument.
Definition: FormatString.h:255
IdentifierInfo * getIdentifier() const
Get the identifier that names this declaration, if there is one.
Definition: Decl.h:269
One of these records is kept for each identifier that is lexed.
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
Definition: ASTContext.h:160
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
Definition: LangOptions.h:49
void setFieldWidth(const OptionalAmount &Amt)
Definition: FormatString.h:448
Represents the length modifier in a format string in scanf/printf.
Definition: FormatString.h:64
CanQualType UnsignedCharTy
Definition: ASTContext.h:1025
OptionalAmount ParseNonPositionAmount(const char *&Beg, const char *E, unsigned &argIndex)
bool isPromotableIntegerType() const
More type predicates useful for type checking/promotion.
Definition: Type.cpp:2563
QualType getPromotedIntegerType(QualType PromotableType) const
Return the type that PromotableType will promote to: C99 6.3.1.1p2, assuming that PromotableType is a...
Exposes information about the current target.
Definition: TargetInfo.h:163
Defines the clang::LangOptions interface.
bool isNullPtrType() const
Definition: Type.h:6675
CanQualType ShortTy
Definition: ASTContext.h:1024
void setVectorNumElts(const OptionalAmount &Amt)
Definition: FormatString.h:440
CanQualType SignedCharTy
Definition: ASTContext.h:1024
bool isVoidPointerType() const
Definition: Type.cpp:521
bool isConstQualified() const
Determine whether this type is const-qualified.
Definition: Type.h:6207
QualType getWideCharType() const
Return the type of wide characters.
Definition: ASTContext.h:1574
A helper class that allows the use of isa/cast/dyncast to detect TagType objects of enums...
Definition: Type.h:4470
virtual void HandleInvalidPosition(const char *startPos, unsigned posLen, PositionContext p)
Definition: FormatString.h:701
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...
QualType getExtVectorType(QualType VectorType, unsigned NumElts) const
Return the unique reference to an extended vector type of the specified element type and size...
QualType getWIntType() const
In C99, this returns a type compatible with the type defined in <stddef.h> as defined by the target...
Definition: ASTContext.h:1588
bool isObjCObjectPointerType() const
Definition: Type.h:6495
bool ParseFieldWidth(FormatStringHandler &H, FormatSpecifier &CS, const char *Start, const char *&Beg, const char *E, unsigned *argIndex)
StringRef getName() const
Return the actual identifier string.
CanQualType UnsignedShortTy
Definition: ASTContext.h:1025
Base class for declarations which introduce a typedef-name.
Definition: Decl.h:2985
CanQualType CharTy
Definition: ASTContext.h:1017
CanQualType ObjCBuiltinIdTy
Definition: ASTContext.h:1047
Dataflow Directional Tag Classes.
QualType getUnderlyingType() const
Definition: Decl.h:3040
CanQualType UnsignedLongLongTy
Definition: ASTContext.h:1026
Optional< LengthModifier > getCorrectedLengthModifier() const
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&#39;t go fur...
Represents a pointer to an Objective C object.
Definition: Type.h:5870
Pointer to a block type.
Definition: Type.h:2687
CanQualType UnsignedLongTy
Definition: ASTContext.h:1025
ArgType getArgType(ASTContext &Ctx) const
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...
CanQualType getCanonicalType(QualType T) const
Return the canonical (structural) type corresponding to the specified potentially non-canonical type ...
Definition: ASTContext.h:2289
bool hasSignedIntegerRepresentation() const
Determine whether this type has an signed integer representation of some sort, e.g., it is an signed integer type or a vector.
Definition: Type.cpp:1961
bool isVoidType() const
Definition: Type.h:6650
virtual void HandleIncompleteSpecifier(const char *startSpecifier, unsigned specifierLen)
Definition: FormatString.h:706
QualType getPointerType(QualType T) const
Return the uniqued reference to the type for a pointer to the specified type.
unsigned kind
All of the diagnostics that can be emitted by the frontend.
Definition: DiagnosticIDs.h:60
This class is used for builtin types like &#39;int&#39;.
Definition: Type.h:2436
Defines the clang::TargetInfo interface.
bool hasStandardConversionSpecifier(const LangOptions &LangOpt) const
OptionalAmount ParseAmount(const char *&Beg, const char *E)
static Decl::Kind getKind(const Decl *D)
Definition: DeclBase.cpp:945
CanQualType IntTy
Definition: ASTContext.h:1024
bool isPointerType() const
Definition: Type.h:6391
Optional< ConversionSpecifier > getStandardSpecifier() const
CanQualType UnsignedIntTy
Definition: ASTContext.h:1025
OptionalAmount ParsePositionAmount(FormatStringHandler &H, const char *Start, const char *&Beg, const char *E, PositionContext p)