clang  9.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  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  return T == C.UnsignedCharTy || T == C.SignedCharTy ? Match
390  : NoMatch;
391  case BuiltinType::Short:
392  return T == C.UnsignedShortTy ? Match : NoMatch;
393  case BuiltinType::UShort:
394  return T == C.ShortTy ? Match : NoMatch;
395  case BuiltinType::Int:
396  return T == C.UnsignedIntTy ? Match : NoMatch;
397  case BuiltinType::UInt:
398  return T == C.IntTy ? Match : NoMatch;
399  case BuiltinType::Long:
400  return T == C.UnsignedLongTy ? Match : NoMatch;
401  case BuiltinType::ULong:
402  return T == C.LongTy ? Match : NoMatch;
403  case BuiltinType::LongLong:
404  return T == C.UnsignedLongLongTy ? Match : NoMatch;
405  case BuiltinType::ULongLong:
406  return T == C.LongLongTy ? Match : NoMatch;
407  }
408  return NoMatch;
409  }
410 
411  case CStrTy: {
412  const PointerType *PT = argTy->getAs<PointerType>();
413  if (!PT)
414  return NoMatch;
415  QualType pointeeTy = PT->getPointeeType();
416  if (const BuiltinType *BT = pointeeTy->getAs<BuiltinType>())
417  switch (BT->getKind()) {
418  case BuiltinType::Void:
419  case BuiltinType::Char_U:
420  case BuiltinType::UChar:
421  case BuiltinType::Char_S:
422  case BuiltinType::SChar:
423  return Match;
424  default:
425  break;
426  }
427 
428  return NoMatch;
429  }
430 
431  case WCStrTy: {
432  const PointerType *PT = argTy->getAs<PointerType>();
433  if (!PT)
434  return NoMatch;
435  QualType pointeeTy =
436  C.getCanonicalType(PT->getPointeeType()).getUnqualifiedType();
437  return pointeeTy == C.getWideCharType() ? Match : NoMatch;
438  }
439 
440  case WIntTy: {
441  QualType WInt = C.getCanonicalType(C.getWIntType()).getUnqualifiedType();
442 
443  if (C.getCanonicalType(argTy).getUnqualifiedType() == WInt)
444  return Match;
445 
446  QualType PromoArg = argTy->isPromotableIntegerType()
447  ? C.getPromotedIntegerType(argTy)
448  : argTy;
449  PromoArg = C.getCanonicalType(PromoArg).getUnqualifiedType();
450 
451  // If the promoted argument is the corresponding signed type of the
452  // wint_t type, then it should match.
453  if (PromoArg->hasSignedIntegerRepresentation() &&
454  C.getCorrespondingUnsignedType(PromoArg) == WInt)
455  return Match;
456 
457  return WInt == PromoArg ? Match : NoMatch;
458  }
459 
460  case CPointerTy:
461  if (argTy->isVoidPointerType()) {
462  return Match;
463  } if (argTy->isPointerType() || argTy->isObjCObjectPointerType() ||
464  argTy->isBlockPointerType() || argTy->isNullPtrType()) {
465  return NoMatchPedantic;
466  } else {
467  return NoMatch;
468  }
469 
470  case ObjCPointerTy: {
471  if (argTy->getAs<ObjCObjectPointerType>() ||
472  argTy->getAs<BlockPointerType>())
473  return Match;
474 
475  // Handle implicit toll-free bridging.
476  if (const PointerType *PT = argTy->getAs<PointerType>()) {
477  // Things such as CFTypeRef are really just opaque pointers
478  // to C structs representing CF types that can often be bridged
479  // to Objective-C objects. Since the compiler doesn't know which
480  // structs can be toll-free bridged, we just accept them all.
481  QualType pointee = PT->getPointeeType();
482  if (pointee->getAsStructureType() || pointee->isVoidType())
483  return Match;
484  }
485  return NoMatch;
486  }
487  }
488 
489  llvm_unreachable("Invalid ArgType Kind!");
490 }
491 
492 ArgType ArgType::makeVectorType(ASTContext &C, unsigned NumElts) const {
493  // Check for valid vector element types.
494  if (T.isNull())
495  return ArgType::Invalid();
496 
497  QualType Vec = C.getExtVectorType(T, NumElts);
498  return ArgType(Vec, Name);
499 }
500 
501 QualType ArgType::getRepresentativeType(ASTContext &C) const {
502  QualType Res;
503  switch (K) {
504  case InvalidTy:
505  llvm_unreachable("No representative type for Invalid ArgType");
506  case UnknownTy:
507  llvm_unreachable("No representative type for Unknown ArgType");
508  case AnyCharTy:
509  Res = C.CharTy;
510  break;
511  case SpecificTy:
512  Res = T;
513  break;
514  case CStrTy:
515  Res = C.getPointerType(C.CharTy);
516  break;
517  case WCStrTy:
518  Res = C.getPointerType(C.getWideCharType());
519  break;
520  case ObjCPointerTy:
521  Res = C.ObjCBuiltinIdTy;
522  break;
523  case CPointerTy:
524  Res = C.VoidPtrTy;
525  break;
526  case WIntTy: {
527  Res = C.getWIntType();
528  break;
529  }
530  }
531 
532  if (Ptr)
533  Res = C.getPointerType(Res);
534  return Res;
535 }
536 
537 std::string ArgType::getRepresentativeTypeName(ASTContext &C) const {
538  std::string S = getRepresentativeType(C).getAsString();
539 
540  std::string Alias;
541  if (Name) {
542  // Use a specific name for this type, e.g. "size_t".
543  Alias = Name;
544  if (Ptr) {
545  // If ArgType is actually a pointer to T, append an asterisk.
546  Alias += (Alias[Alias.size()-1] == '*') ? "*" : " *";
547  }
548  // If Alias is the same as the underlying type, e.g. wchar_t, then drop it.
549  if (S == Alias)
550  Alias.clear();
551  }
552 
553  if (!Alias.empty())
554  return std::string("'") + Alias + "' (aka '" + S + "')";
555  return std::string("'") + S + "'";
556 }
557 
558 
559 //===----------------------------------------------------------------------===//
560 // Methods on OptionalAmount.
561 //===----------------------------------------------------------------------===//
562 
563 ArgType
565  return Ctx.IntTy;
566 }
567 
568 //===----------------------------------------------------------------------===//
569 // Methods on LengthModifier.
570 //===----------------------------------------------------------------------===//
571 
572 const char *
574  switch (kind) {
575  case AsChar:
576  return "hh";
577  case AsShort:
578  return "h";
579  case AsShortLong:
580  return "hl";
581  case AsLong: // or AsWideChar
582  return "l";
583  case AsLongLong:
584  return "ll";
585  case AsQuad:
586  return "q";
587  case AsIntMax:
588  return "j";
589  case AsSizeT:
590  return "z";
591  case AsPtrDiff:
592  return "t";
593  case AsInt32:
594  return "I32";
595  case AsInt3264:
596  return "I";
597  case AsInt64:
598  return "I64";
599  case AsLongDouble:
600  return "L";
601  case AsAllocate:
602  return "a";
603  case AsMAllocate:
604  return "m";
605  case AsWide:
606  return "w";
607  case None:
608  return "";
609  }
610  return nullptr;
611 }
612 
613 //===----------------------------------------------------------------------===//
614 // Methods on ConversionSpecifier.
615 //===----------------------------------------------------------------------===//
616 
617 const char *ConversionSpecifier::toString() const {
618  switch (kind) {
619  case dArg: return "d";
620  case DArg: return "D";
621  case iArg: return "i";
622  case oArg: return "o";
623  case OArg: return "O";
624  case uArg: return "u";
625  case UArg: return "U";
626  case xArg: return "x";
627  case XArg: return "X";
628  case fArg: return "f";
629  case FArg: return "F";
630  case eArg: return "e";
631  case EArg: return "E";
632  case gArg: return "g";
633  case GArg: return "G";
634  case aArg: return "a";
635  case AArg: return "A";
636  case cArg: return "c";
637  case sArg: return "s";
638  case pArg: return "p";
639  case PArg:
640  return "P";
641  case nArg: return "n";
642  case PercentArg: return "%";
643  case ScanListArg: return "[";
644  case InvalidSpecifier: return nullptr;
645 
646  // POSIX unicode extensions.
647  case CArg: return "C";
648  case SArg: return "S";
649 
650  // Objective-C specific specifiers.
651  case ObjCObjArg: return "@";
652 
653  // FreeBSD kernel specific specifiers.
654  case FreeBSDbArg: return "b";
655  case FreeBSDDArg: return "D";
656  case FreeBSDrArg: return "r";
657  case FreeBSDyArg: return "y";
658 
659  // GlibC specific specifiers.
660  case PrintErrno: return "m";
661 
662  // MS specific specifiers.
663  case ZArg: return "Z";
664  }
665  return nullptr;
666 }
667 
671 
672  switch (getKind()) {
673  default:
674  return None;
675  case DArg:
676  NewKind = dArg;
677  break;
678  case UArg:
679  NewKind = uArg;
680  break;
681  case OArg:
682  NewKind = oArg;
683  break;
684  }
685 
686  ConversionSpecifier FixedCS(*this);
687  FixedCS.setKind(NewKind);
688  return FixedCS;
689 }
690 
691 //===----------------------------------------------------------------------===//
692 // Methods on OptionalAmount.
693 //===----------------------------------------------------------------------===//
694 
695 void OptionalAmount::toString(raw_ostream &os) const {
696  switch (hs) {
697  case Invalid:
698  case NotSpecified:
699  return;
700  case Arg:
701  if (UsesDotPrefix)
702  os << ".";
703  if (usesPositionalArg())
704  os << "*" << getPositionalArgIndex() << "$";
705  else
706  os << "*";
707  break;
708  case Constant:
709  if (UsesDotPrefix)
710  os << ".";
711  os << amt;
712  break;
713  }
714 }
715 
717  const LangOptions &LO) const {
718  switch (LM.getKind()) {
720  return true;
721 
722  // Handle most integer flags
724  // Length modifier only applies to FP vectors.
725  if (LO.OpenCL && CS.isDoubleArg())
726  return !VectorNumElts.isInvalid();
727 
728  if (Target.getTriple().isOSMSVCRT()) {
729  switch (CS.getKind()) {
735  return true;
736  default:
737  break;
738  }
739  }
740  LLVM_FALLTHROUGH;
747  switch (CS.getKind()) {
758  return true;
761  return Target.getTriple().isOSFreeBSD() || Target.getTriple().isPS4();
762  default:
763  return false;
764  }
765 
767  return LO.OpenCL && !VectorNumElts.isInvalid();
768 
769  // Handle 'l' flag
770  case LengthModifier::AsLong: // or AsWideChar
771  if (CS.isDoubleArg()) {
772  // Invalid for OpenCL FP scalars.
773  if (LO.OpenCL && VectorNumElts.isInvalid())
774  return false;
775  return true;
776  }
777 
778  switch (CS.getKind()) {
793  return true;
796  return Target.getTriple().isOSFreeBSD() || Target.getTriple().isPS4();
797  default:
798  return false;
799  }
800 
802  switch (CS.getKind()) {
811  return true;
812  // GNU libc extension.
819  return !Target.getTriple().isOSDarwin() &&
820  !Target.getTriple().isOSWindows();
821  default:
822  return false;
823  }
824 
826  switch (CS.getKind()) {
830  return true;
831  default:
832  return false;
833  }
834 
836  switch (CS.getKind()) {
842  return true;
843  default:
844  return false;
845  }
849  switch (CS.getKind()) {
856  return Target.getTriple().isOSMSVCRT();
857  default:
858  return false;
859  }
861  switch (CS.getKind()) {
867  return Target.getTriple().isOSMSVCRT();
868  default:
869  return false;
870  }
871  }
872  llvm_unreachable("Invalid LengthModifier Kind!");
873 }
874 
876  switch (LM.getKind()) {
886  return true;
894  case LengthModifier::AsShortLong: // ???
895  return false;
896  }
897  llvm_unreachable("Invalid LengthModifier Kind!");
898 }
899 
901  const LangOptions &LangOpt) const {
902  switch (CS.getKind()) {
925  return true;
928  return LangOpt.ObjC;
939  return false;
940  }
941  llvm_unreachable("Invalid ConversionSpecifier Kind!");
942 }
943 
945  if (LM.getKind() == LengthModifier::AsLongDouble) {
946  switch(CS.getKind()) {
953  return false;
954  default:
955  return true;
956  }
957  }
958  return true;
959 }
960 
962  if (CS.isAnyIntArg() || CS.getKind() == ConversionSpecifier::nArg) {
963  if (LM.getKind() == LengthModifier::AsLongDouble ||
964  LM.getKind() == LengthModifier::AsQuad) {
965  LengthModifier FixedLM(LM);
967  return FixedLM;
968  }
969  }
970 
971  return None;
972 }
973 
975  LengthModifier &LM) {
976  assert(isa<TypedefType>(QT) && "Expected a TypedefType");
977  const TypedefNameDecl *Typedef = cast<TypedefType>(QT)->getDecl();
978 
979  for (;;) {
980  const IdentifierInfo *Identifier = Typedef->getIdentifier();
981  if (Identifier->getName() == "size_t") {
983  return true;
984  } else if (Identifier->getName() == "ssize_t") {
985  // Not C99, but common in Unix.
987  return true;
988  } else if (Identifier->getName() == "intmax_t") {
990  return true;
991  } else if (Identifier->getName() == "uintmax_t") {
993  return true;
994  } else if (Identifier->getName() == "ptrdiff_t") {
996  return true;
997  }
998 
999  QualType T = Typedef->getUnderlyingType();
1000  if (!isa<TypedefType>(T))
1001  break;
1002 
1003  Typedef = cast<TypedefType>(T)->getDecl();
1004  }
1005  return false;
1006 }
virtual void HandlePosition(const char *startPos, unsigned posLen)
Definition: FormatString.h:685
CanQualType LongLongTy
Definition: ASTContext.h:1024
StringRef Identifier
Definition: Format.cpp:1714
PointerType - C99 6.7.5.1 - Pointer Declarators.
Definition: Type.h:2549
CanQualType VoidPtrTy
Definition: ASTContext.h:1043
QualType getPointeeType() const
Definition: Type.h:2562
A (possibly-)qualified type.
Definition: Type.h:639
bool isBlockPointerType() const
Definition: Type.h:6316
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:505
const llvm::Triple & getTriple() const
Returns the target triple of the primary target.
Definition: TargetInfo.h:966
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:690
const RecordType * getAsStructureType() const
Definition: Type.cpp:521
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:6768
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:154
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:434
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:2533
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:161
Defines the clang::LangOptions interface.
bool isNullPtrType() const
Definition: Type.h:6585
CanQualType ShortTy
Definition: ASTContext.h:1024
void setVectorNumElts(const OptionalAmount &Amt)
Definition: FormatString.h:426
CanQualType SignedCharTy
Definition: ASTContext.h:1024
bool isVoidPointerType() const
Definition: Type.cpp:469
bool isConstQualified() const
Determine whether this type is const-qualified.
Definition: Type.h:6143
QualType getWideCharType() const
Return the type of wide characters.
Definition: ASTContext.h:1564
A helper class that allows the use of isa/cast/dyncast to detect TagType objects of enums...
Definition: Type.h:4408
virtual void HandleInvalidPosition(const char *startPos, unsigned posLen, PositionContext p)
Definition: FormatString.h:687
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:1578
bool isObjCObjectPointerType() const
Definition: Type.h:6405
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:2915
CanQualType CharTy
Definition: ASTContext.h:1017
CanQualType ObjCBuiltinIdTy
Definition: ASTContext.h:1047
Dataflow Directional Tag Classes.
QualType getUnderlyingType() const
Definition: Decl.h:2970
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:5806
Pointer to a block type.
Definition: Type.h:2651
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:2266
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:1896
bool isVoidType() const
Definition: Type.h:6560
virtual void HandleIncompleteSpecifier(const char *startSpecifier, unsigned specifierLen)
Definition: FormatString.h:692
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:2403
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:957
CanQualType IntTy
Definition: ASTContext.h:1024
bool isPointerType() const
Definition: Type.h:6308
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)