1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
11 | |
12 | |
13 | |
14 | #include "FormatStringParsing.h" |
15 | #include "clang/Basic/LangOptions.h" |
16 | #include "clang/Basic/TargetInfo.h" |
17 | #include "llvm/Support/ConvertUTF.h" |
18 | |
19 | using clang::analyze_format_string::ArgType; |
20 | using clang::analyze_format_string::FormatStringHandler; |
21 | using clang::analyze_format_string::FormatSpecifier; |
22 | using clang::analyze_format_string::LengthModifier; |
23 | using clang::analyze_format_string::OptionalAmount; |
24 | using clang::analyze_format_string::PositionContext; |
25 | using clang::analyze_format_string::ConversionSpecifier; |
26 | using namespace clang; |
27 | |
28 | |
29 | FormatStringHandler::~FormatStringHandler() {} |
30 | |
31 | |
32 | |
33 | |
34 | |
35 | |
36 | OptionalAmount |
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 | |
62 | OptionalAmount |
63 | clang::analyze_format_string::ParseNonPositionAmount(const char *&Beg, |
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 | |
74 | OptionalAmount |
75 | clang::analyze_format_string::ParsePositionAmount(FormatStringHandler &H, |
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 | |
91 | H.HandleIncompleteSpecifier(Start, E - Start); |
92 | return OptionalAmount(false); |
93 | } |
94 | |
95 | assert(Amt.getHowSpecified() == OptionalAmount::Constant); |
96 | |
97 | if (*I == '$') { |
98 | |
99 | |
100 | |
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 |
122 | clang::analyze_format_string::ParseFieldWidth(FormatStringHandler &H, |
123 | FormatSpecifier &CS, |
124 | const char *Start, |
125 | const char *&Beg, const char *E, |
126 | unsigned *argIndex) { |
127 | |
128 | if (argIndex) { |
129 | CS.setFieldWidth(ParseNonPositionAmount(Beg, E, *argIndex)); |
130 | } |
131 | else { |
132 | const OptionalAmount Amt = |
133 | ParsePositionAmount(H, Start, Beg, E, |
134 | analyze_format_string::FieldWidthPos); |
135 | |
136 | if (Amt.isInvalid()) |
137 | return true; |
138 | CS.setFieldWidth(Amt); |
139 | } |
140 | return false; |
141 | } |
142 | |
143 | bool |
144 | clang::analyze_format_string::ParseArgPosition(FormatStringHandler &H, |
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 | |
155 | H.HandleIncompleteSpecifier(Start, E - Start); |
156 | return true; |
157 | } |
158 | |
159 | if (Amt.getHowSpecified() == OptionalAmount::Constant && *(I++) == '$') { |
160 | |
161 | H.HandlePosition(Start, I - Start); |
162 | |
163 | |
164 | if (Amt.getConstantAmount() == 0) { |
165 | H.HandleZeroPosition(Start, I - Start); |
166 | return true; |
167 | } |
168 | |
169 | FS.setArgIndex(Amt.getConstantAmount() - 1); |
170 | FS.setUsesPositionalArg(); |
171 | |
172 | |
173 | Beg = I; |
174 | return false; |
175 | } |
176 | |
177 | return false; |
178 | } |
179 | |
180 | bool |
181 | clang::analyze_format_string::ParseVectorModifier(FormatStringHandler &H, |
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 |
211 | clang::analyze_format_string::ParseLengthModifier(FormatSpecifier &FS, |
212 | const char *&I, |
213 | const char *E, |
214 | const LangOptions &LO, |
215 | bool IsScanf) { |
216 | LengthModifier::Kind lmKind = LengthModifier::None; |
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 | |
250 | |
251 | |
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 | |
268 | |
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 | |
296 | bool clang::analyze_format_string::ParseUTF8InvalidSpecifier( |
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 | |
307 | |
308 | |
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 | |
321 | |
322 | |
323 | clang::analyze_format_string::ArgType::MatchKind |
324 | ArgType::matchesType(ASTContext &C, QualType argTy) const { |
325 | if (Ptr) { |
326 | |
327 | const PointerType *PT = argTy->getAs<PointerType>(); |
328 | if (!PT) |
329 | return NoMatch; |
330 | |
331 | |
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 | |
348 | |
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 | |
370 | |
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 | |
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 | |
452 | |
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 | |
476 | if (const PointerType *PT = argTy->getAs<PointerType>()) { |
477 | |
478 | |
479 | |
480 | |
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 | |
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 | |
543 | Alias = Name; |
544 | if (Ptr) { |
545 | |
546 | Alias += (Alias[Alias.size()-1] == '*') ? "*" : " *"; |
547 | } |
548 | |
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 | |
561 | |
562 | |
563 | ArgType |
564 | analyze_format_string::OptionalAmount::getArgType(ASTContext &Ctx) const { |
565 | return Ctx.IntTy; |
566 | } |
567 | |
568 | |
569 | |
570 | |
571 | |
572 | const char * |
573 | analyze_format_string::LengthModifier::toString() const { |
574 | switch (kind) { |
575 | case AsChar: |
576 | return "hh"; |
577 | case AsShort: |
578 | return "h"; |
579 | case AsShortLong: |
580 | return "hl"; |
581 | case AsLong: |
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 | |
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 | |
647 | case CArg: return "C"; |
648 | case SArg: return "S"; |
649 | |
650 | |
651 | case ObjCObjArg: return "@"; |
652 | |
653 | |
654 | case FreeBSDbArg: return "b"; |
655 | case FreeBSDDArg: return "D"; |
656 | case FreeBSDrArg: return "r"; |
657 | case FreeBSDyArg: return "y"; |
658 | |
659 | |
660 | case PrintErrno: return "m"; |
661 | |
662 | |
663 | case ZArg: return "Z"; |
664 | } |
665 | return nullptr; |
666 | } |
667 | |
668 | Optional<ConversionSpecifier> |
669 | ConversionSpecifier::getStandardSpecifier() const { |
670 | ConversionSpecifier::Kind NewKind; |
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 | |
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 | |
716 | bool FormatSpecifier::hasValidLengthModifier(const TargetInfo &Target, |
717 | const LangOptions &LO) const { |
718 | switch (LM.getKind()) { |
719 | case LengthModifier::None: |
720 | return true; |
721 | |
722 | |
723 | case LengthModifier::AsShort: |
724 | |
725 | if (LO.OpenCL && CS.isDoubleArg()) |
726 | return !VectorNumElts.isInvalid(); |
727 | |
728 | if (Target.getTriple().isOSMSVCRT()) { |
729 | switch (CS.getKind()) { |
730 | case ConversionSpecifier::cArg: |
731 | case ConversionSpecifier::CArg: |
732 | case ConversionSpecifier::sArg: |
733 | case ConversionSpecifier::SArg: |
734 | case ConversionSpecifier::ZArg: |
735 | return true; |
736 | default: |
737 | break; |
738 | } |
739 | } |
740 | LLVM_FALLTHROUGH; |
741 | case LengthModifier::AsChar: |
742 | case LengthModifier::AsLongLong: |
743 | case LengthModifier::AsQuad: |
744 | case LengthModifier::AsIntMax: |
745 | case LengthModifier::AsSizeT: |
746 | case LengthModifier::AsPtrDiff: |
747 | switch (CS.getKind()) { |
748 | case ConversionSpecifier::dArg: |
749 | case ConversionSpecifier::DArg: |
750 | case ConversionSpecifier::iArg: |
751 | case ConversionSpecifier::oArg: |
752 | case ConversionSpecifier::OArg: |
753 | case ConversionSpecifier::uArg: |
754 | case ConversionSpecifier::UArg: |
755 | case ConversionSpecifier::xArg: |
756 | case ConversionSpecifier::XArg: |
757 | case ConversionSpecifier::nArg: |
758 | return true; |
759 | case ConversionSpecifier::FreeBSDrArg: |
760 | case ConversionSpecifier::FreeBSDyArg: |
761 | return Target.getTriple().isOSFreeBSD() || Target.getTriple().isPS4(); |
762 | default: |
763 | return false; |
764 | } |
765 | |
766 | case LengthModifier::AsShortLong: |
767 | return LO.OpenCL && !VectorNumElts.isInvalid(); |
768 | |
769 | |
770 | case LengthModifier::AsLong: |
771 | if (CS.isDoubleArg()) { |
772 | |
773 | if (LO.OpenCL && VectorNumElts.isInvalid()) |
774 | return false; |
775 | return true; |
776 | } |
777 | |
778 | switch (CS.getKind()) { |
779 | case ConversionSpecifier::dArg: |
780 | case ConversionSpecifier::DArg: |
781 | case ConversionSpecifier::iArg: |
782 | case ConversionSpecifier::oArg: |
783 | case ConversionSpecifier::OArg: |
784 | case ConversionSpecifier::uArg: |
785 | case ConversionSpecifier::UArg: |
786 | case ConversionSpecifier::xArg: |
787 | case ConversionSpecifier::XArg: |
788 | case ConversionSpecifier::nArg: |
789 | case ConversionSpecifier::cArg: |
790 | case ConversionSpecifier::sArg: |
791 | case ConversionSpecifier::ScanListArg: |
792 | case ConversionSpecifier::ZArg: |
793 | return true; |
794 | case ConversionSpecifier::FreeBSDrArg: |
795 | case ConversionSpecifier::FreeBSDyArg: |
796 | return Target.getTriple().isOSFreeBSD() || Target.getTriple().isPS4(); |
797 | default: |
798 | return false; |
799 | } |
800 | |
801 | case LengthModifier::AsLongDouble: |
802 | switch (CS.getKind()) { |
803 | case ConversionSpecifier::aArg: |
804 | case ConversionSpecifier::AArg: |
805 | case ConversionSpecifier::fArg: |
806 | case ConversionSpecifier::FArg: |
807 | case ConversionSpecifier::eArg: |
808 | case ConversionSpecifier::EArg: |
809 | case ConversionSpecifier::gArg: |
810 | case ConversionSpecifier::GArg: |
811 | return true; |
812 | |
813 | case ConversionSpecifier::dArg: |
814 | case ConversionSpecifier::iArg: |
815 | case ConversionSpecifier::oArg: |
816 | case ConversionSpecifier::uArg: |
817 | case ConversionSpecifier::xArg: |
818 | case ConversionSpecifier::XArg: |
819 | return !Target.getTriple().isOSDarwin() && |
820 | !Target.getTriple().isOSWindows(); |
821 | default: |
822 | return false; |
823 | } |
824 | |
825 | case LengthModifier::AsAllocate: |
826 | switch (CS.getKind()) { |
827 | case ConversionSpecifier::sArg: |
828 | case ConversionSpecifier::SArg: |
829 | case ConversionSpecifier::ScanListArg: |
830 | return true; |
831 | default: |
832 | return false; |
833 | } |
834 | |
835 | case LengthModifier::AsMAllocate: |
836 | switch (CS.getKind()) { |
837 | case ConversionSpecifier::cArg: |
838 | case ConversionSpecifier::CArg: |
839 | case ConversionSpecifier::sArg: |
840 | case ConversionSpecifier::SArg: |
841 | case ConversionSpecifier::ScanListArg: |
842 | return true; |
843 | default: |
844 | return false; |
845 | } |
846 | case LengthModifier::AsInt32: |
847 | case LengthModifier::AsInt3264: |
848 | case LengthModifier::AsInt64: |
849 | switch (CS.getKind()) { |
850 | case ConversionSpecifier::dArg: |
851 | case ConversionSpecifier::iArg: |
852 | case ConversionSpecifier::oArg: |
853 | case ConversionSpecifier::uArg: |
854 | case ConversionSpecifier::xArg: |
855 | case ConversionSpecifier::XArg: |
856 | return Target.getTriple().isOSMSVCRT(); |
857 | default: |
858 | return false; |
859 | } |
860 | case LengthModifier::AsWide: |
861 | switch (CS.getKind()) { |
862 | case ConversionSpecifier::cArg: |
863 | case ConversionSpecifier::CArg: |
864 | case ConversionSpecifier::sArg: |
865 | case ConversionSpecifier::SArg: |
866 | case ConversionSpecifier::ZArg: |
867 | return Target.getTriple().isOSMSVCRT(); |
868 | default: |
869 | return false; |
870 | } |
871 | } |
872 | llvm_unreachable("Invalid LengthModifier Kind!"); |
873 | } |
874 | |
875 | bool FormatSpecifier::hasStandardLengthModifier() const { |
876 | switch (LM.getKind()) { |
877 | case LengthModifier::None: |
878 | case LengthModifier::AsChar: |
879 | case LengthModifier::AsShort: |
880 | case LengthModifier::AsLong: |
881 | case LengthModifier::AsLongLong: |
882 | case LengthModifier::AsIntMax: |
883 | case LengthModifier::AsSizeT: |
884 | case LengthModifier::AsPtrDiff: |
885 | case LengthModifier::AsLongDouble: |
886 | return true; |
887 | case LengthModifier::AsAllocate: |
888 | case LengthModifier::AsMAllocate: |
889 | case LengthModifier::AsQuad: |
890 | case LengthModifier::AsInt32: |
891 | case LengthModifier::AsInt3264: |
892 | case LengthModifier::AsInt64: |
893 | case LengthModifier::AsWide: |
894 | case LengthModifier::AsShortLong: |
895 | return false; |
896 | } |
897 | llvm_unreachable("Invalid LengthModifier Kind!"); |
898 | } |
899 | |
900 | bool FormatSpecifier::hasStandardConversionSpecifier( |
901 | const LangOptions &LangOpt) const { |
902 | switch (CS.getKind()) { |
903 | case ConversionSpecifier::cArg: |
904 | case ConversionSpecifier::dArg: |
905 | case ConversionSpecifier::iArg: |
906 | case ConversionSpecifier::oArg: |
907 | case ConversionSpecifier::uArg: |
908 | case ConversionSpecifier::xArg: |
909 | case ConversionSpecifier::XArg: |
910 | case ConversionSpecifier::fArg: |
911 | case ConversionSpecifier::FArg: |
912 | case ConversionSpecifier::eArg: |
913 | case ConversionSpecifier::EArg: |
914 | case ConversionSpecifier::gArg: |
915 | case ConversionSpecifier::GArg: |
916 | case ConversionSpecifier::aArg: |
917 | case ConversionSpecifier::AArg: |
918 | case ConversionSpecifier::sArg: |
919 | case ConversionSpecifier::pArg: |
920 | case ConversionSpecifier::nArg: |
921 | case ConversionSpecifier::ObjCObjArg: |
922 | case ConversionSpecifier::ScanListArg: |
923 | case ConversionSpecifier::PercentArg: |
924 | case ConversionSpecifier::PArg: |
925 | return true; |
926 | case ConversionSpecifier::CArg: |
927 | case ConversionSpecifier::SArg: |
928 | return LangOpt.ObjC; |
929 | case ConversionSpecifier::InvalidSpecifier: |
930 | case ConversionSpecifier::FreeBSDbArg: |
931 | case ConversionSpecifier::FreeBSDDArg: |
932 | case ConversionSpecifier::FreeBSDrArg: |
933 | case ConversionSpecifier::FreeBSDyArg: |
934 | case ConversionSpecifier::PrintErrno: |
935 | case ConversionSpecifier::DArg: |
936 | case ConversionSpecifier::OArg: |
937 | case ConversionSpecifier::UArg: |
938 | case ConversionSpecifier::ZArg: |
939 | return false; |
940 | } |
941 | llvm_unreachable("Invalid ConversionSpecifier Kind!"); |
942 | } |
943 | |
944 | bool FormatSpecifier::hasStandardLengthConversionCombination() const { |
945 | if (LM.getKind() == LengthModifier::AsLongDouble) { |
946 | switch(CS.getKind()) { |
947 | case ConversionSpecifier::dArg: |
948 | case ConversionSpecifier::iArg: |
949 | case ConversionSpecifier::oArg: |
950 | case ConversionSpecifier::uArg: |
951 | case ConversionSpecifier::xArg: |
952 | case ConversionSpecifier::XArg: |
953 | return false; |
954 | default: |
955 | return true; |
956 | } |
957 | } |
958 | return true; |
959 | } |
960 | |
961 | Optional<LengthModifier> FormatSpecifier::getCorrectedLengthModifier() const { |
962 | if (CS.isAnyIntArg() || CS.getKind() == ConversionSpecifier::nArg) { |
963 | if (LM.getKind() == LengthModifier::AsLongDouble || |
964 | LM.getKind() == LengthModifier::AsQuad) { |
965 | LengthModifier FixedLM(LM); |
966 | FixedLM.setKind(LengthModifier::AsLongLong); |
967 | return FixedLM; |
968 | } |
969 | } |
970 | |
971 | return None; |
972 | } |
973 | |
974 | bool FormatSpecifier::namedTypeToLengthModifier(QualType QT, |
975 | LengthModifier &LM) { |
976 | (0) . __assert_fail ("isa(QT) && \"Expected a TypedefType\"", "/home/seafit/code_projects/clang_source/clang/lib/AST/FormatString.cpp", 976, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">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") { |
982 | LM.setKind(LengthModifier::AsSizeT); |
983 | return true; |
984 | } else if (Identifier->getName() == "ssize_t") { |
985 | |
986 | LM.setKind(LengthModifier::AsSizeT); |
987 | return true; |
988 | } else if (Identifier->getName() == "intmax_t") { |
989 | LM.setKind(LengthModifier::AsIntMax); |
990 | return true; |
991 | } else if (Identifier->getName() == "uintmax_t") { |
992 | LM.setKind(LengthModifier::AsIntMax); |
993 | return true; |
994 | } else if (Identifier->getName() == "ptrdiff_t") { |
995 | LM.setKind(LengthModifier::AsPtrDiff); |
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 | } |
1007 | |