1 // FormatString.cpp - Common stuff for handling printf/scanf formats -*- C++ -*-
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
7 //===----------------------------------------------------------------------===//
9 // Shared details for processing format strings of printf and scanf
12 //===----------------------------------------------------------------------===//
14 #include "FormatStringParsing.h"
15 #include "clang/Basic/LangOptions.h"
16 #include "clang/Basic/TargetInfo.h"
17 #include "llvm/Support/ConvertUTF.h"
20 using clang::analyze_format_string::ArgType
;
21 using clang::analyze_format_string::FormatStringHandler
;
22 using clang::analyze_format_string::FormatSpecifier
;
23 using clang::analyze_format_string::LengthModifier
;
24 using clang::analyze_format_string::OptionalAmount
;
25 using clang::analyze_format_string::ConversionSpecifier
;
26 using namespace clang
;
28 // Key function to FormatStringHandler.
29 FormatStringHandler::~FormatStringHandler() {}
31 //===----------------------------------------------------------------------===//
32 // Functions for parsing format strings components in both printf and
33 // scanf format strings.
34 //===----------------------------------------------------------------------===//
37 clang::analyze_format_string::ParseAmount(const char *&Beg
, const char *E
) {
39 UpdateOnReturn
<const char*> UpdateBeg(Beg
, I
);
41 unsigned accumulator
= 0;
42 bool hasDigits
= false;
44 for ( ; I
!= E
; ++I
) {
46 if (c
>= '0' && c
<= '9') {
48 accumulator
= (accumulator
* 10) + (c
- '0');
53 return OptionalAmount(OptionalAmount::Constant
, accumulator
, Beg
, I
- Beg
,
59 return OptionalAmount();
63 clang::analyze_format_string::ParseNonPositionAmount(const char *&Beg
,
68 return OptionalAmount(OptionalAmount::Arg
, argIndex
++, Beg
, 0, false);
71 return ParseAmount(Beg
, E
);
75 clang::analyze_format_string::ParsePositionAmount(FormatStringHandler
&H
,
81 const char *I
= Beg
+ 1;
82 const OptionalAmount
&Amt
= ParseAmount(I
, E
);
84 if (Amt
.getHowSpecified() == OptionalAmount::NotSpecified
) {
85 H
.HandleInvalidPosition(Beg
, I
- Beg
, p
);
86 return OptionalAmount(false);
90 // No more characters left?
91 H
.HandleIncompleteSpecifier(Start
, E
- Start
);
92 return OptionalAmount(false);
95 assert(Amt
.getHowSpecified() == OptionalAmount::Constant
);
98 // Handle positional arguments
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);
106 const char *Tmp
= Beg
;
109 return OptionalAmount(OptionalAmount::Arg
, Amt
.getConstantAmount() - 1,
113 H
.HandleInvalidPosition(Beg
, I
- Beg
, p
);
114 return OptionalAmount(false);
117 return ParseAmount(Beg
, E
);
122 clang::analyze_format_string::ParseFieldWidth(FormatStringHandler
&H
,
125 const char *&Beg
, const char *E
,
126 unsigned *argIndex
) {
127 // FIXME: Support negative field widths.
129 CS
.setFieldWidth(ParseNonPositionAmount(Beg
, E
, *argIndex
));
132 const OptionalAmount Amt
=
133 ParsePositionAmount(H
, Start
, Beg
, E
,
134 analyze_format_string::FieldWidthPos
);
138 CS
.setFieldWidth(Amt
);
144 clang::analyze_format_string::ParseArgPosition(FormatStringHandler
&H
,
151 const OptionalAmount
&Amt
= ParseAmount(I
, E
);
154 // No more characters left?
155 H
.HandleIncompleteSpecifier(Start
, E
- Start
);
159 if (Amt
.getHowSpecified() == OptionalAmount::Constant
&& *(I
++) == '$') {
160 // Warn that positional arguments are non-standard.
161 H
.HandlePosition(Start
, I
- Start
);
163 // Special case: '%0$', since this is an easy mistake.
164 if (Amt
.getConstantAmount() == 0) {
165 H
.HandleZeroPosition(Start
, I
- Start
);
169 FS
.setArgIndex(Amt
.getConstantAmount() - 1);
170 FS
.setUsesPositionalArg();
171 // Update the caller's pointer if we decided to consume
181 clang::analyze_format_string::ParseVectorModifier(FormatStringHandler
&H
,
185 const LangOptions
&LO
) {
189 const char *Start
= I
;
194 H
.HandleIncompleteSpecifier(Start
, E
- Start
);
198 OptionalAmount NumElts
= ParseAmount(I
, E
);
199 if (NumElts
.getHowSpecified() != OptionalAmount::Constant
) {
200 H
.HandleIncompleteSpecifier(Start
, E
- Start
);
204 FS
.setVectorNumElts(NumElts
);
211 clang::analyze_format_string::ParseLengthModifier(FormatSpecifier
&FS
,
214 const LangOptions
&LO
,
216 LengthModifier::Kind lmKind
= LengthModifier::None
;
217 const char *lmPosition
= I
;
223 if (I
!= E
&& *I
== 'h') {
225 lmKind
= LengthModifier::AsChar
;
226 } else if (I
!= E
&& *I
== 'l' && LO
.OpenCL
) {
228 lmKind
= LengthModifier::AsShortLong
;
230 lmKind
= LengthModifier::AsShort
;
235 if (I
!= E
&& *I
== 'l') {
237 lmKind
= LengthModifier::AsLongLong
;
239 lmKind
= LengthModifier::AsLong
;
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;
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.
253 if (I
!= E
&& (*I
== 's' || *I
== 'S' || *I
== '[')) {
254 lmKind
= LengthModifier::AsAllocate
;
262 lmKind
= LengthModifier::AsMAllocate
;
267 // printf: AsInt64, AsInt32, AsInt3264
270 if (I
+ 1 != E
&& I
+ 2 != E
) {
271 if (I
[1] == '6' && I
[2] == '4') {
273 lmKind
= LengthModifier::AsInt64
;
279 if (I
[1] == '3' && I
[2] == '2') {
281 lmKind
= LengthModifier::AsInt32
;
286 lmKind
= LengthModifier::AsInt3264
;
289 lmKind
= LengthModifier::AsWide
; ++I
; break;
291 LengthModifier
lm(lmPosition
, lmKind
);
292 FS
.setLengthModifier(lm
);
296 bool clang::analyze_format_string::ParseUTF8InvalidSpecifier(
297 const char *SpecifierBegin
, const char *FmtStrEnd
, unsigned &Len
) {
298 if (SpecifierBegin
+ 1 >= FmtStrEnd
)
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
;
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
);
312 if (SB
+ NumBytes
> SE
)
319 //===----------------------------------------------------------------------===//
320 // Methods on ArgType.
321 //===----------------------------------------------------------------------===//
323 clang::analyze_format_string::ArgType::MatchKind
324 ArgType::matchesType(ASTContext
&C
, QualType argTy
) const {
325 // When using the format attribute in C++, you can receive a function or an
326 // array that will necessarily decay to a pointer when passed to the final
327 // format consumer. Apply decay before type comparison.
328 if (argTy
->canDecayToPointerType())
329 argTy
= C
.getDecayedType(argTy
);
332 // It has to be a pointer.
333 const PointerType
*PT
= argTy
->getAs
<PointerType
>();
337 // We cannot write through a const qualified pointer.
338 if (PT
->getPointeeType().isConstQualified())
341 argTy
= PT
->getPointeeType();
346 llvm_unreachable("ArgType must be valid");
352 if (const auto *ETy
= argTy
->getAs
<EnumType
>()) {
353 // If the enum is incomplete we know nothing about the underlying type.
354 // Assume that it's 'int'. Do not use the underlying type for a scoped
356 if (!ETy
->getDecl()->isComplete())
358 if (ETy
->isUnscopedEnumerationType())
359 argTy
= ETy
->getDecl()->getIntegerType();
362 if (const auto *BT
= argTy
->getAs
<BuiltinType
>()) {
363 // The types are perfectly matched?
364 switch (BT
->getKind()) {
367 case BuiltinType::Char_S
:
368 case BuiltinType::SChar
:
369 case BuiltinType::UChar
:
370 case BuiltinType::Char_U
:
372 case BuiltinType::Bool
:
377 // "Partially matched" because of promotions?
379 switch (BT
->getKind()) {
382 case BuiltinType::Int
:
383 case BuiltinType::UInt
:
384 return MatchPromotion
;
385 case BuiltinType::Short
:
386 case BuiltinType::UShort
:
387 case BuiltinType::WChar_S
:
388 case BuiltinType::WChar_U
:
389 return NoMatchPromotionTypeConfusion
;
397 if (const EnumType
*ETy
= argTy
->getAs
<EnumType
>()) {
398 // If the enum is incomplete we know nothing about the underlying type.
399 // Assume that it's 'int'. Do not use the underlying type for a scoped
400 // enumeration as that needs an exact match.
401 if (!ETy
->getDecl()->isComplete())
403 else if (ETy
->isUnscopedEnumerationType())
404 argTy
= ETy
->getDecl()->getIntegerType();
406 argTy
= C
.getCanonicalType(argTy
).getUnqualifiedType();
410 if (const auto *BT
= argTy
->getAs
<BuiltinType
>()) {
411 // Check if the only difference between them is signed vs unsigned
412 // if true, we consider they are compatible.
413 switch (BT
->getKind()) {
416 case BuiltinType::Bool
:
417 if (Ptr
&& (T
== C
.UnsignedCharTy
|| T
== C
.SignedCharTy
))
420 case BuiltinType::Char_S
:
421 case BuiltinType::SChar
:
422 case BuiltinType::Char_U
:
423 case BuiltinType::UChar
:
424 if (T
== C
.UnsignedShortTy
|| T
== C
.ShortTy
)
425 return NoMatchTypeConfusion
;
426 if (T
== C
.UnsignedCharTy
|| T
== C
.SignedCharTy
)
429 case BuiltinType::Short
:
430 if (T
== C
.UnsignedShortTy
)
433 case BuiltinType::UShort
:
437 case BuiltinType::Int
:
438 if (T
== C
.UnsignedIntTy
)
441 case BuiltinType::UInt
:
445 case BuiltinType::Long
:
446 if (T
== C
.UnsignedLongTy
)
449 case BuiltinType::ULong
:
453 case BuiltinType::LongLong
:
454 if (T
== C
.UnsignedLongLongTy
)
457 case BuiltinType::ULongLong
:
458 if (T
== C
.LongLongTy
)
462 // "Partially matched" because of promotions?
464 switch (BT
->getKind()) {
467 case BuiltinType::Bool
:
468 if (T
== C
.IntTy
|| T
== C
.UnsignedIntTy
)
469 return MatchPromotion
;
471 case BuiltinType::Int
:
472 case BuiltinType::UInt
:
473 if (T
== C
.SignedCharTy
|| T
== C
.UnsignedCharTy
||
474 T
== C
.ShortTy
|| T
== C
.UnsignedShortTy
|| T
== C
.WCharTy
||
476 return MatchPromotion
;
478 case BuiltinType::Char_U
:
479 if (T
== C
.UnsignedIntTy
)
480 return MatchPromotion
;
481 if (T
== C
.UnsignedShortTy
)
482 return NoMatchPromotionTypeConfusion
;
484 case BuiltinType::Char_S
:
486 return MatchPromotion
;
488 return NoMatchPromotionTypeConfusion
;
490 case BuiltinType::Half
:
491 case BuiltinType::Float16
:
492 case BuiltinType::Float
:
494 return MatchPromotion
;
496 case BuiltinType::Short
:
497 case BuiltinType::UShort
:
498 if (T
== C
.SignedCharTy
|| T
== C
.UnsignedCharTy
)
499 return NoMatchPromotionTypeConfusion
;
501 case BuiltinType::WChar_U
:
502 case BuiltinType::WChar_S
:
503 if (T
!= C
.WCharTy
&& T
!= C
.WideCharTy
)
504 return NoMatchPromotionTypeConfusion
;
512 const PointerType
*PT
= argTy
->getAs
<PointerType
>();
515 QualType pointeeTy
= PT
->getPointeeType();
516 if (const BuiltinType
*BT
= pointeeTy
->getAs
<BuiltinType
>())
517 switch (BT
->getKind()) {
518 case BuiltinType::Char_U
:
519 case BuiltinType::UChar
:
520 case BuiltinType::Char_S
:
521 case BuiltinType::SChar
:
531 const PointerType
*PT
= argTy
->getAs
<PointerType
>();
535 C
.getCanonicalType(PT
->getPointeeType()).getUnqualifiedType();
536 return pointeeTy
== C
.getWideCharType() ? Match
: NoMatch
;
540 QualType WInt
= C
.getCanonicalType(C
.getWIntType()).getUnqualifiedType();
542 if (C
.getCanonicalType(argTy
).getUnqualifiedType() == WInt
)
545 QualType PromoArg
= C
.isPromotableIntegerType(argTy
)
546 ? C
.getPromotedIntegerType(argTy
)
548 PromoArg
= C
.getCanonicalType(PromoArg
).getUnqualifiedType();
550 // If the promoted argument is the corresponding signed type of the
551 // wint_t type, then it should match.
552 if (PromoArg
->hasSignedIntegerRepresentation() &&
553 C
.getCorrespondingUnsignedType(PromoArg
) == WInt
)
556 return WInt
== PromoArg
? Match
: NoMatch
;
560 if (argTy
->isVoidPointerType()) {
562 } if (argTy
->isPointerType() || argTy
->isObjCObjectPointerType() ||
563 argTy
->isBlockPointerType() || argTy
->isNullPtrType()) {
564 return NoMatchPedantic
;
569 case ObjCPointerTy
: {
570 if (argTy
->getAs
<ObjCObjectPointerType
>() ||
571 argTy
->getAs
<BlockPointerType
>())
574 // Handle implicit toll-free bridging.
575 if (const PointerType
*PT
= argTy
->getAs
<PointerType
>()) {
576 // Things such as CFTypeRef are really just opaque pointers
577 // to C structs representing CF types that can often be bridged
578 // to Objective-C objects. Since the compiler doesn't know which
579 // structs can be toll-free bridged, we just accept them all.
580 QualType pointee
= PT
->getPointeeType();
581 if (pointee
->getAsStructureType() || pointee
->isVoidType())
588 llvm_unreachable("Invalid ArgType Kind!");
591 ArgType
ArgType::makeVectorType(ASTContext
&C
, unsigned NumElts
) const {
592 // Check for valid vector element types.
594 return ArgType::Invalid();
596 QualType Vec
= C
.getExtVectorType(T
, NumElts
);
597 return ArgType(Vec
, Name
);
600 QualType
ArgType::getRepresentativeType(ASTContext
&C
) const {
604 llvm_unreachable("No representative type for Invalid ArgType");
606 llvm_unreachable("No representative type for Unknown ArgType");
614 Res
= C
.getPointerType(C
.CharTy
);
617 Res
= C
.getPointerType(C
.getWideCharType());
620 Res
= C
.ObjCBuiltinIdTy
;
626 Res
= C
.getWIntType();
632 Res
= C
.getPointerType(Res
);
636 std::string
ArgType::getRepresentativeTypeName(ASTContext
&C
) const {
637 std::string S
= getRepresentativeType(C
).getAsString(C
.getPrintingPolicy());
641 // Use a specific name for this type, e.g. "size_t".
644 // If ArgType is actually a pointer to T, append an asterisk.
645 Alias
+= (Alias
[Alias
.size()-1] == '*') ? "*" : " *";
647 // If Alias is the same as the underlying type, e.g. wchar_t, then drop it.
653 return std::string("'") + Alias
+ "' (aka '" + S
+ "')";
654 return std::string("'") + S
+ "'";
658 //===----------------------------------------------------------------------===//
659 // Methods on OptionalAmount.
660 //===----------------------------------------------------------------------===//
663 analyze_format_string::OptionalAmount::getArgType(ASTContext
&Ctx
) const {
667 //===----------------------------------------------------------------------===//
668 // Methods on LengthModifier.
669 //===----------------------------------------------------------------------===//
672 analyze_format_string::LengthModifier::toString() const {
680 case AsLong
: // or AsWideChar
712 //===----------------------------------------------------------------------===//
713 // Methods on ConversionSpecifier.
714 //===----------------------------------------------------------------------===//
716 const char *ConversionSpecifier::toString() const {
718 case bArg
: return "b";
719 case BArg
: return "B";
720 case dArg
: return "d";
721 case DArg
: return "D";
722 case iArg
: return "i";
723 case oArg
: return "o";
724 case OArg
: return "O";
725 case uArg
: return "u";
726 case UArg
: return "U";
727 case xArg
: return "x";
728 case XArg
: return "X";
729 case fArg
: return "f";
730 case FArg
: return "F";
731 case eArg
: return "e";
732 case EArg
: return "E";
733 case gArg
: return "g";
734 case GArg
: return "G";
735 case aArg
: return "a";
736 case AArg
: return "A";
737 case cArg
: return "c";
738 case sArg
: return "s";
739 case pArg
: return "p";
742 case nArg
: return "n";
743 case PercentArg
: return "%";
744 case ScanListArg
: return "[";
745 case InvalidSpecifier
: return nullptr;
747 // POSIX unicode extensions.
748 case CArg
: return "C";
749 case SArg
: return "S";
751 // Objective-C specific specifiers.
752 case ObjCObjArg
: return "@";
754 // FreeBSD kernel specific specifiers.
755 case FreeBSDbArg
: return "b";
756 case FreeBSDDArg
: return "D";
757 case FreeBSDrArg
: return "r";
758 case FreeBSDyArg
: return "y";
760 // GlibC specific specifiers.
761 case PrintErrno
: return "m";
763 // MS specific specifiers.
764 case ZArg
: return "Z";
769 std::optional
<ConversionSpecifier
>
770 ConversionSpecifier::getStandardSpecifier() const {
771 ConversionSpecifier::Kind NewKind
;
787 ConversionSpecifier
FixedCS(*this);
788 FixedCS
.setKind(NewKind
);
792 //===----------------------------------------------------------------------===//
793 // Methods on OptionalAmount.
794 //===----------------------------------------------------------------------===//
796 void OptionalAmount::toString(raw_ostream
&os
) const {
804 if (usesPositionalArg())
805 os
<< "*" << getPositionalArgIndex() << "$";
817 bool FormatSpecifier::hasValidLengthModifier(const TargetInfo
&Target
,
818 const LangOptions
&LO
) const {
819 switch (LM
.getKind()) {
820 case LengthModifier::None
:
823 // Handle most integer flags
824 case LengthModifier::AsShort
:
825 // Length modifier only applies to FP vectors.
826 if (LO
.OpenCL
&& CS
.isDoubleArg())
827 return !VectorNumElts
.isInvalid();
829 if (Target
.getTriple().isOSMSVCRT()) {
830 switch (CS
.getKind()) {
831 case ConversionSpecifier::cArg
:
832 case ConversionSpecifier::CArg
:
833 case ConversionSpecifier::sArg
:
834 case ConversionSpecifier::SArg
:
835 case ConversionSpecifier::ZArg
:
842 case LengthModifier::AsChar
:
843 case LengthModifier::AsLongLong
:
844 case LengthModifier::AsQuad
:
845 case LengthModifier::AsIntMax
:
846 case LengthModifier::AsSizeT
:
847 case LengthModifier::AsPtrDiff
:
848 switch (CS
.getKind()) {
849 case ConversionSpecifier::bArg
:
850 case ConversionSpecifier::BArg
:
851 case ConversionSpecifier::dArg
:
852 case ConversionSpecifier::DArg
:
853 case ConversionSpecifier::iArg
:
854 case ConversionSpecifier::oArg
:
855 case ConversionSpecifier::OArg
:
856 case ConversionSpecifier::uArg
:
857 case ConversionSpecifier::UArg
:
858 case ConversionSpecifier::xArg
:
859 case ConversionSpecifier::XArg
:
860 case ConversionSpecifier::nArg
:
862 case ConversionSpecifier::FreeBSDrArg
:
863 case ConversionSpecifier::FreeBSDyArg
:
864 return Target
.getTriple().isOSFreeBSD() || Target
.getTriple().isPS();
869 case LengthModifier::AsShortLong
:
870 return LO
.OpenCL
&& !VectorNumElts
.isInvalid();
873 case LengthModifier::AsLong
: // or AsWideChar
874 if (CS
.isDoubleArg()) {
875 // Invalid for OpenCL FP scalars.
876 if (LO
.OpenCL
&& VectorNumElts
.isInvalid())
881 switch (CS
.getKind()) {
882 case ConversionSpecifier::bArg
:
883 case ConversionSpecifier::BArg
:
884 case ConversionSpecifier::dArg
:
885 case ConversionSpecifier::DArg
:
886 case ConversionSpecifier::iArg
:
887 case ConversionSpecifier::oArg
:
888 case ConversionSpecifier::OArg
:
889 case ConversionSpecifier::uArg
:
890 case ConversionSpecifier::UArg
:
891 case ConversionSpecifier::xArg
:
892 case ConversionSpecifier::XArg
:
893 case ConversionSpecifier::nArg
:
894 case ConversionSpecifier::cArg
:
895 case ConversionSpecifier::sArg
:
896 case ConversionSpecifier::ScanListArg
:
897 case ConversionSpecifier::ZArg
:
899 case ConversionSpecifier::FreeBSDrArg
:
900 case ConversionSpecifier::FreeBSDyArg
:
901 return Target
.getTriple().isOSFreeBSD() || Target
.getTriple().isPS();
906 case LengthModifier::AsLongDouble
:
907 switch (CS
.getKind()) {
908 case ConversionSpecifier::aArg
:
909 case ConversionSpecifier::AArg
:
910 case ConversionSpecifier::fArg
:
911 case ConversionSpecifier::FArg
:
912 case ConversionSpecifier::eArg
:
913 case ConversionSpecifier::EArg
:
914 case ConversionSpecifier::gArg
:
915 case ConversionSpecifier::GArg
:
917 // GNU libc extension.
918 case ConversionSpecifier::dArg
:
919 case ConversionSpecifier::iArg
:
920 case ConversionSpecifier::oArg
:
921 case ConversionSpecifier::uArg
:
922 case ConversionSpecifier::xArg
:
923 case ConversionSpecifier::XArg
:
924 return !Target
.getTriple().isOSDarwin() &&
925 !Target
.getTriple().isOSWindows();
930 case LengthModifier::AsAllocate
:
931 switch (CS
.getKind()) {
932 case ConversionSpecifier::sArg
:
933 case ConversionSpecifier::SArg
:
934 case ConversionSpecifier::ScanListArg
:
940 case LengthModifier::AsMAllocate
:
941 switch (CS
.getKind()) {
942 case ConversionSpecifier::cArg
:
943 case ConversionSpecifier::CArg
:
944 case ConversionSpecifier::sArg
:
945 case ConversionSpecifier::SArg
:
946 case ConversionSpecifier::ScanListArg
:
951 case LengthModifier::AsInt32
:
952 case LengthModifier::AsInt3264
:
953 case LengthModifier::AsInt64
:
954 switch (CS
.getKind()) {
955 case ConversionSpecifier::dArg
:
956 case ConversionSpecifier::iArg
:
957 case ConversionSpecifier::oArg
:
958 case ConversionSpecifier::uArg
:
959 case ConversionSpecifier::xArg
:
960 case ConversionSpecifier::XArg
:
961 return Target
.getTriple().isOSMSVCRT();
965 case LengthModifier::AsWide
:
966 switch (CS
.getKind()) {
967 case ConversionSpecifier::cArg
:
968 case ConversionSpecifier::CArg
:
969 case ConversionSpecifier::sArg
:
970 case ConversionSpecifier::SArg
:
971 case ConversionSpecifier::ZArg
:
972 return Target
.getTriple().isOSMSVCRT();
977 llvm_unreachable("Invalid LengthModifier Kind!");
980 bool FormatSpecifier::hasStandardLengthModifier() const {
981 switch (LM
.getKind()) {
982 case LengthModifier::None
:
983 case LengthModifier::AsChar
:
984 case LengthModifier::AsShort
:
985 case LengthModifier::AsLong
:
986 case LengthModifier::AsLongLong
:
987 case LengthModifier::AsIntMax
:
988 case LengthModifier::AsSizeT
:
989 case LengthModifier::AsPtrDiff
:
990 case LengthModifier::AsLongDouble
:
992 case LengthModifier::AsAllocate
:
993 case LengthModifier::AsMAllocate
:
994 case LengthModifier::AsQuad
:
995 case LengthModifier::AsInt32
:
996 case LengthModifier::AsInt3264
:
997 case LengthModifier::AsInt64
:
998 case LengthModifier::AsWide
:
999 case LengthModifier::AsShortLong
: // ???
1002 llvm_unreachable("Invalid LengthModifier Kind!");
1005 bool FormatSpecifier::hasStandardConversionSpecifier(
1006 const LangOptions
&LangOpt
) const {
1007 switch (CS
.getKind()) {
1008 case ConversionSpecifier::bArg
:
1009 case ConversionSpecifier::BArg
:
1010 case ConversionSpecifier::cArg
:
1011 case ConversionSpecifier::dArg
:
1012 case ConversionSpecifier::iArg
:
1013 case ConversionSpecifier::oArg
:
1014 case ConversionSpecifier::uArg
:
1015 case ConversionSpecifier::xArg
:
1016 case ConversionSpecifier::XArg
:
1017 case ConversionSpecifier::fArg
:
1018 case ConversionSpecifier::FArg
:
1019 case ConversionSpecifier::eArg
:
1020 case ConversionSpecifier::EArg
:
1021 case ConversionSpecifier::gArg
:
1022 case ConversionSpecifier::GArg
:
1023 case ConversionSpecifier::aArg
:
1024 case ConversionSpecifier::AArg
:
1025 case ConversionSpecifier::sArg
:
1026 case ConversionSpecifier::pArg
:
1027 case ConversionSpecifier::nArg
:
1028 case ConversionSpecifier::ObjCObjArg
:
1029 case ConversionSpecifier::ScanListArg
:
1030 case ConversionSpecifier::PercentArg
:
1031 case ConversionSpecifier::PArg
:
1033 case ConversionSpecifier::CArg
:
1034 case ConversionSpecifier::SArg
:
1035 return LangOpt
.ObjC
;
1036 case ConversionSpecifier::InvalidSpecifier
:
1037 case ConversionSpecifier::FreeBSDbArg
:
1038 case ConversionSpecifier::FreeBSDDArg
:
1039 case ConversionSpecifier::FreeBSDrArg
:
1040 case ConversionSpecifier::FreeBSDyArg
:
1041 case ConversionSpecifier::PrintErrno
:
1042 case ConversionSpecifier::DArg
:
1043 case ConversionSpecifier::OArg
:
1044 case ConversionSpecifier::UArg
:
1045 case ConversionSpecifier::ZArg
:
1048 llvm_unreachable("Invalid ConversionSpecifier Kind!");
1051 bool FormatSpecifier::hasStandardLengthConversionCombination() const {
1052 if (LM
.getKind() == LengthModifier::AsLongDouble
) {
1053 switch(CS
.getKind()) {
1054 case ConversionSpecifier::dArg
:
1055 case ConversionSpecifier::iArg
:
1056 case ConversionSpecifier::oArg
:
1057 case ConversionSpecifier::uArg
:
1058 case ConversionSpecifier::xArg
:
1059 case ConversionSpecifier::XArg
:
1068 std::optional
<LengthModifier
>
1069 FormatSpecifier::getCorrectedLengthModifier() const {
1070 if (CS
.isAnyIntArg() || CS
.getKind() == ConversionSpecifier::nArg
) {
1071 if (LM
.getKind() == LengthModifier::AsLongDouble
||
1072 LM
.getKind() == LengthModifier::AsQuad
) {
1073 LengthModifier
FixedLM(LM
);
1074 FixedLM
.setKind(LengthModifier::AsLongLong
);
1079 return std::nullopt
;
1082 bool FormatSpecifier::namedTypeToLengthModifier(QualType QT
,
1083 LengthModifier
&LM
) {
1084 for (/**/; const auto *TT
= QT
->getAs
<TypedefType
>();
1085 QT
= TT
->getDecl()->getUnderlyingType()) {
1086 const TypedefNameDecl
*Typedef
= TT
->getDecl();
1087 const IdentifierInfo
*Identifier
= Typedef
->getIdentifier();
1088 if (Identifier
->getName() == "size_t") {
1089 LM
.setKind(LengthModifier::AsSizeT
);
1091 } else if (Identifier
->getName() == "ssize_t") {
1092 // Not C99, but common in Unix.
1093 LM
.setKind(LengthModifier::AsSizeT
);
1095 } else if (Identifier
->getName() == "intmax_t") {
1096 LM
.setKind(LengthModifier::AsIntMax
);
1098 } else if (Identifier
->getName() == "uintmax_t") {
1099 LM
.setKind(LengthModifier::AsIntMax
);
1101 } else if (Identifier
->getName() == "ptrdiff_t") {
1102 LM
.setKind(LengthModifier::AsPtrDiff
);