clang 23.0.0git
FormatString.h
Go to the documentation of this file.
1//= FormatString.h - Analysis of printf/fprintf format strings --*- 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// This file defines APIs for analyzing the format strings of printf, fscanf,
10// and friends.
11//
12// The structure of format strings for fprintf are described in C99 7.19.6.1.
13//
14// The structure of format strings for fscanf are described in C99 7.19.6.2.
15//
16//===----------------------------------------------------------------------===//
17
18#ifndef LLVM_CLANG_AST_FORMATSTRING_H
19#define LLVM_CLANG_AST_FORMATSTRING_H
20
22#include <optional>
23
24namespace clang {
25
26class TargetInfo;
27
28//===----------------------------------------------------------------------===//
29/// Common components of both fprintf and fscanf format strings.
31
32/// Class representing optional flags with location and representation
33/// information.
35public:
36 OptionalFlag(const char *Representation)
37 : representation(Representation), flag(false) {}
38 bool isSet() const { return flag; }
39 void set() { flag = true; }
40 void clear() { flag = false; }
41 void setPosition(const char *position) {
42 assert(position);
43 flag = true;
44 this->position = position;
45 }
46 const char *getPosition() const {
47 assert(position);
48 return position;
49 }
50 const char *toString() const { return representation; }
51
52 // Overloaded operators for bool like qualities
53 explicit operator bool() const { return flag; }
54 OptionalFlag &operator=(const bool &rhs) {
55 flag = rhs;
56 return *this; // Return a reference to myself.
57 }
58
59private:
60 const char *representation;
61 const char *position;
62 bool flag;
63};
64
65/// Represents the length modifier in a format string in scanf/printf.
67public:
68 enum Kind {
70 AsChar, // 'hh'
71 AsShort, // 'h'
72 AsShortLong, // 'hl' (OpenCL float/int vector element)
73 AsLong, // 'l'
74 AsLongLong, // 'll'
75 AsQuad, // 'q' (BSD, deprecated, for 64-bit integer types)
76 AsIntMax, // 'j'
77 AsSizeT, // 'z'
78 AsPtrDiff, // 't'
79 AsInt32, // 'I32' (MSVCRT, like __int32)
80 AsInt3264, // 'I' (MSVCRT, like __int3264 from MIDL)
81 AsInt64, // 'I64' (MSVCRT, like __int64)
83 AsAllocate, // for '%as', GNU extension to C90 scanf
84 AsMAllocate, // for '%ms', GNU extension to scanf
85 AsWide, // 'w' (MSVCRT, like l but only for c, C, s, S, or Z
86 AsWideChar = AsLong // for '%ls', only makes sense for printf
87 };
88
89 LengthModifier() : Position(nullptr), kind(None) {}
90 LengthModifier(const char *pos, Kind k) : Position(pos), kind(k) {}
91
92 const char *getStart() const { return Position; }
93
94 unsigned getLength() const {
95 switch (kind) {
96 default:
97 return 1;
98 case AsLongLong:
99 case AsChar:
100 return 2;
101 case AsInt32:
102 case AsInt64:
103 return 3;
104 case None:
105 return 0;
106 }
107 }
108
109 Kind getKind() const { return kind; }
110 void setKind(Kind k) { kind = k; }
111
112 const char *toString() const;
113
114private:
115 const char *Position;
116 Kind kind;
117};
118
120public:
121 enum Kind {
123 // C99 conversion specifiers.
126 DArg, // Apple extension
128 // C23 conversion specifiers.
131
134
136 OArg, // Apple extension
138 UArg, // Apple extension
143
154
161
162 // Apple extension: P specifies to os_log that the data being pointed to is
163 // to be copied by os_log. The precision indicates the number of bytes to
164 // copy.
166
167 // ** Printf-specific **
168
169 ZArg, // MS extension
170
171 // ISO/IEC TR 18037 (fixed-point) specific specifiers.
172 kArg, // %k for signed accum types
173 KArg, // %K for unsigned accum types
174 rArg, // %r for signed fract types
175 RArg, // %R for unsigned fract types
178
179 // Objective-C specific specifiers.
183
184 // FreeBSD kernel specific specifiers.
189
190 // GlibC specific specifiers.
192
195
196 // ** Scanf-specific **
200 };
201
202 ConversionSpecifier(bool isPrintf = true)
205
206 ConversionSpecifier(bool isPrintf, const char *pos, Kind k)
207 : IsPrintf(isPrintf), Position(pos), EndScanList(nullptr), kind(k) {}
208
209 const char *getStart() const { return Position; }
210
211 StringRef getCharacters() const { return StringRef(getStart(), getLength()); }
212
213 bool consumesDataArgument() const {
214 switch (kind) {
215 case PrintErrno:
216 assert(IsPrintf);
217 return false;
218 case PercentArg:
219 return false;
220 case InvalidSpecifier:
221 return false;
222 default:
223 return true;
224 }
225 }
226
227 Kind getKind() const { return kind; }
228 void setKind(Kind k) { kind = k; }
229 unsigned getLength() const {
230 return EndScanList ? EndScanList - Position : 1;
231 }
232 void setEndScanList(const char *pos) { EndScanList = pos; }
233
234 bool isIntArg() const {
235 return (kind >= IntArgBeg && kind <= IntArgEnd) || kind == FreeBSDrArg ||
236 kind == FreeBSDyArg;
237 }
238 bool isUIntArg() const { return kind >= UIntArgBeg && kind <= UIntArgEnd; }
239 bool isAnyIntArg() const { return kind >= IntArgBeg && kind <= UIntArgEnd; }
240 bool isDoubleArg() const {
241 return kind >= DoubleArgBeg && kind <= DoubleArgEnd;
242 }
243 bool isFixedPointArg() const {
245 }
246
247 const char *toString() const;
248
249 bool isPrintfKind() const { return IsPrintf; }
250
251 std::optional<ConversionSpecifier> getStandardSpecifier() const;
252
253protected:
255 const char *Position;
256 const char *EndScanList;
258};
259
260class ArgType {
261public:
273
274 /// How well a given conversion specifier matches its argument.
276 /// The conversion specifier and the argument types are incompatible. For
277 /// instance, "%d" and float.
279 /// The conversion specifier and the argument type are compatible. For
280 /// instance, "%d" and int.
281 Match = 1,
282 /// The conversion specifier and the argument type are compatible because of
283 /// default argument promotions. For instance, "%hhd" and int.
285 /// The conversion specifier and the argument type are compatible but still
286 /// seems likely to be an error. For instanace, "%hhd" and short.
288 /// The conversion specifier and the argument type are disallowed by the C
289 /// standard, but are in practice harmless. For instance, "%p" and int*.
291 /// The conversion specifier and the argument type have different sign.
293 /// The conversion specifier and the argument type are compatible, but still
294 /// seems likely to be an error. For instance, "%hd" and _Bool.
296 };
297
298private:
299 Kind K;
300 QualType T;
301 const char *Name = nullptr;
302 bool Ptr = false;
303
304 /// The TypeKind identifies certain well-known types like size_t and
305 /// ptrdiff_t.
306 enum class TypeKind { DontCare, SizeT, PtrdiffT };
307 TypeKind TK = TypeKind::DontCare;
308
309public:
310 ArgType(Kind K = UnknownTy, const char *N = nullptr) : K(K), Name(N) {}
311 ArgType(QualType T, const char *N = nullptr) : K(SpecificTy), T(T), Name(N) {}
313
314 static ArgType Invalid() { return ArgType(InvalidTy); }
315 bool isValid() const { return K != InvalidTy; }
316
317 bool isSizeT() const { return TK == TypeKind::SizeT; }
318
319 bool isPtrdiffT() const { return TK == TypeKind::PtrdiffT; }
320
321 /// Create an ArgType which corresponds to the type pointer to A.
322 static ArgType PtrTo(const ArgType &A) {
323 assert(A.K >= InvalidTy && "ArgType cannot be pointer to invalid/unknown");
324 ArgType Res = A;
325 Res.Ptr = true;
326 return Res;
327 }
328
329 /// Create an ArgType which corresponds to the size_t/ssize_t type.
330 static ArgType makeSizeT(const ArgType &A) {
331 ArgType Res = A;
332 Res.TK = TypeKind::SizeT;
333 return Res;
334 }
335
336 /// Create an ArgType which corresponds to the ptrdiff_t/unsigned ptrdiff_t
337 /// type.
338 static ArgType makePtrdiffT(const ArgType &A) {
339 ArgType Res = A;
340 Res.TK = TypeKind::PtrdiffT;
341 return Res;
342 }
343
345 MatchKind matchesArgType(ASTContext &C, const ArgType &other) const;
346
348
349 ArgType makeVectorType(ASTContext &C, unsigned NumElts) const;
350
351 std::string getRepresentativeTypeName(ASTContext &C) const;
352};
353
355public:
357
358 OptionalAmount(HowSpecified howSpecified, unsigned amount,
359 const char *amountStart, unsigned amountLength,
361 : start(amountStart), length(amountLength), hs(howSpecified), amt(amount),
362 UsesPositionalArg(usesPositionalArg), UsesDotPrefix(false) {}
363
364 OptionalAmount(bool valid = true)
365 : start(nullptr), length(0), hs(valid ? NotSpecified : Invalid), amt(0),
366 UsesPositionalArg(false), UsesDotPrefix(false) {}
367
368 explicit OptionalAmount(unsigned Amount)
369 : start(nullptr), length(0), hs(Constant), amt(Amount),
370 UsesPositionalArg(false), UsesDotPrefix(false) {}
371
372 bool isInvalid() const { return hs == Invalid; }
373
374 HowSpecified getHowSpecified() const { return hs; }
375 void setHowSpecified(HowSpecified h) { hs = h; }
376
377 bool hasDataArgument() const { return hs == Arg; }
378
379 unsigned getArgIndex() const {
380 assert(hasDataArgument());
381 return amt;
382 }
383
384 unsigned getConstantAmount() const {
385 assert(hs == Constant);
386 return amt;
387 }
388
389 const char *getStart() const {
390 // We include the . character if it is given.
391 return start - UsesDotPrefix;
392 }
393
394 unsigned getConstantLength() const {
395 assert(hs == Constant);
396 return length + UsesDotPrefix;
397 }
398
399 StringRef getCharacters() const {
400 return StringRef(start - UsesDotPrefix, length + UsesDotPrefix);
401 }
402
403 ArgType getArgType(ASTContext &Ctx) const;
404
405 void toString(raw_ostream &os) const;
406
407 bool usesPositionalArg() const { return (bool)UsesPositionalArg; }
408 unsigned getPositionalArgIndex() const {
409 assert(hasDataArgument());
410 return amt + 1;
411 }
412
413 bool usesDotPrefix() const { return UsesDotPrefix; }
414 void setUsesDotPrefix() { UsesDotPrefix = true; }
415
416private:
417 const char *start;
418 unsigned length;
419 HowSpecified hs;
420 unsigned amt;
421 bool UsesPositionalArg : 1;
422 bool UsesDotPrefix;
423};
424
426protected:
431
432 /// Positional arguments, an IEEE extension:
433 /// IEEE Std 1003.1, 2004 Edition
434 /// http://www.opengroup.org/onlinepubs/009695399/functions/printf.html
436 unsigned argIndex;
437
438public:
439 FormatSpecifier(bool isPrintf)
441 argIndex(0) {}
442
444
446
447 void setArgIndex(unsigned i) { argIndex = i; }
448
449 unsigned getArgIndex() const { return argIndex; }
450
451 unsigned getPositionalArgIndex() const { return argIndex + 1; }
452
453 const LengthModifier &getLengthModifier() const { return LM; }
454
455 const OptionalAmount &getFieldWidth() const { return FieldWidth; }
456
458
460
461 void setFieldWidth(const OptionalAmount &Amt) { FieldWidth = Amt; }
462
463 bool usesPositionalArg() const { return UsesPositionalArg; }
464
466 const LangOptions &LO) const;
467
468 bool hasStandardLengthModifier() const;
469
470 std::optional<LengthModifier> getCorrectedLengthModifier() const;
471
472 bool hasStandardConversionSpecifier(const LangOptions &LangOpt) const;
473
475
476 /// For a TypedefType QT, if it is a named integer type such as size_t,
477 /// assign the appropriate value to LM and return true.
478 static bool namedTypeToLengthModifier(ASTContext &Ctx, QualType QT,
480};
481
482} // namespace analyze_format_string
483
484//===----------------------------------------------------------------------===//
485/// Pieces specific to fprintf format strings.
486
487namespace analyze_printf {
488
491public:
494
495 PrintfConversionSpecifier(const char *pos, Kind k)
496 : ConversionSpecifier(true, pos, k) {}
497
498 bool isObjCArg() const { return kind >= ObjCBeg && kind <= ObjCEnd; }
499 bool isDoubleArg() const {
500 return kind >= DoubleArgBeg && kind <= DoubleArgEnd;
501 }
502
504 return CS->isPrintfKind();
505 }
506};
507
512
514 OptionalFlag HasThousandsGrouping; // ''', POSIX extension.
515 OptionalFlag IsLeftJustified; // '-'
516 OptionalFlag HasPlusPrefix; // '+'
517 OptionalFlag HasSpacePrefix; // ' '
518 OptionalFlag HasAlternativeForm; // '#'
519 OptionalFlag HasLeadingZeroes; // '0'
520 OptionalFlag HasObjCTechnicalTerm; // '[tt]'
521 OptionalFlag IsPrivate; // '{private}'
522 OptionalFlag IsPublic; // '{public}'
523 OptionalFlag IsSensitive; // '{sensitive}'
524 OptionalAmount Precision;
525 StringRef MaskType;
526
527 ArgType getScalarArgType(ASTContext &Ctx, bool IsObjCLiteral) const;
528
529public:
531 : FormatSpecifier(/* isPrintf = */ true), HasThousandsGrouping("'"),
532 IsLeftJustified("-"), HasPlusPrefix("+"), HasSpacePrefix(" "),
533 HasAlternativeForm("#"), HasLeadingZeroes("0"),
534 HasObjCTechnicalTerm("tt"), IsPrivate("private"), IsPublic("public"),
535 IsSensitive("sensitive") {}
536
537 static PrintfSpecifier Parse(const char *beg, const char *end);
538
539 // Methods for incrementally constructing the PrintfSpecifier.
541 void setHasThousandsGrouping(const char *position) {
542 HasThousandsGrouping.setPosition(position);
543 }
544 void setIsLeftJustified(const char *position) {
545 IsLeftJustified.setPosition(position);
546 }
547 void setHasPlusPrefix(const char *position) {
548 HasPlusPrefix.setPosition(position);
549 }
550 void setHasSpacePrefix(const char *position) {
551 HasSpacePrefix.setPosition(position);
552 }
553 void setHasAlternativeForm(const char *position) {
554 HasAlternativeForm.setPosition(position);
555 }
556 void setHasLeadingZeros(const char *position) {
557 HasLeadingZeroes.setPosition(position);
558 }
559 void setHasObjCTechnicalTerm(const char *position) {
560 HasObjCTechnicalTerm.setPosition(position);
561 }
562 void setIsPrivate(const char *position) { IsPrivate.setPosition(position); }
563 void setIsPublic(const char *position) { IsPublic.setPosition(position); }
564 void setIsSensitive(const char *position) {
565 IsSensitive.setPosition(position);
566 }
568
569 // Methods for querying the format specifier.
570
574
575 void setPrecision(const OptionalAmount &Amt) {
576 Precision = Amt;
577 Precision.setUsesDotPrefix();
578 }
579
580 const OptionalAmount &getPrecision() const { return Precision; }
581
585
586 /// Returns the builtin type that a data argument
587 /// paired with this format specifier should have. This method
588 /// will return null if the format specifier does not have
589 /// a matching data argument or the matching argument matches
590 /// more than one type.
591 ArgType getArgType(ASTContext &Ctx, bool IsObjCLiteral) const;
592
594 return HasThousandsGrouping;
595 }
596 const OptionalFlag &isLeftJustified() const { return IsLeftJustified; }
597 const OptionalFlag &hasPlusPrefix() const { return HasPlusPrefix; }
598 const OptionalFlag &hasAlternativeForm() const { return HasAlternativeForm; }
599 const OptionalFlag &hasLeadingZeros() const { return HasLeadingZeroes; }
600 const OptionalFlag &hasSpacePrefix() const { return HasSpacePrefix; }
602 return HasObjCTechnicalTerm;
603 }
604 const OptionalFlag &isPrivate() const { return IsPrivate; }
605 const OptionalFlag &isPublic() const { return IsPublic; }
606 const OptionalFlag &isSensitive() const { return IsSensitive; }
607 bool usesPositionalArg() const { return UsesPositionalArg; }
608
609 StringRef getMaskType() const { return MaskType; }
610 void setMaskType(StringRef S) { MaskType = S; }
611
612 /// Changes the specifier and length according to a QualType, retaining any
613 /// flags or options. Returns true on success, or false when a conversion
614 /// was not successful.
615 bool fixType(QualType QT, const LangOptions &LangOpt, ASTContext &Ctx,
616 bool IsObjCLiteral);
617
618 void toString(raw_ostream &os) const;
619
620 // Validation methods - to check if any element results in undefined behavior
621 bool hasValidPlusPrefix() const;
622 bool hasValidAlternativeForm() const;
623 bool hasValidLeadingZeros() const;
624 bool hasValidSpacePrefix() const;
625 bool hasValidLeftJustified() const;
627
628 bool hasValidPrecision() const;
629 bool hasValidFieldWidth() const;
630};
631} // namespace analyze_printf
632
633//===----------------------------------------------------------------------===//
634/// Pieces specific to fscanf format strings.
635
636namespace analyze_scanf {
637
651
656
658 OptionalFlag SuppressAssignment; // '*'
659public:
661 : FormatSpecifier(/* isPrintf = */ false), SuppressAssignment("*") {}
662
663 void setSuppressAssignment(const char *position) {
664 SuppressAssignment.setPosition(position);
665 }
666
668 return SuppressAssignment;
669 }
670
672
676
677 bool consumesDataArgument() const {
678 return CS.consumesDataArgument() && !SuppressAssignment;
679 }
680
681 ArgType getArgType(ASTContext &Ctx) const;
682
683 bool fixType(QualType QT, QualType RawQT, const LangOptions &LangOpt,
684 ASTContext &Ctx);
685
686 void toString(raw_ostream &os) const;
687
688 static ScanfSpecifier Parse(const char *beg, const char *end);
689};
690
691} // namespace analyze_scanf
692
693//===----------------------------------------------------------------------===//
694// Parsing and processing of format strings (both fprintf and fscanf).
695
696namespace analyze_format_string {
697
699
701public:
703 virtual ~FormatStringHandler();
704
705 virtual void HandleNullChar(const char *nullCharacter) {}
706
707 virtual void HandlePosition(const char *startPos, unsigned posLen) {}
708
709 virtual void HandleInvalidPosition(const char *startPos, unsigned posLen,
710 PositionContext p) {}
711
712 virtual void HandleZeroPosition(const char *startPos, unsigned posLen) {}
713
714 virtual void HandleIncompleteSpecifier(const char *startSpecifier,
715 unsigned specifierLen) {}
716
717 virtual void HandleEmptyObjCModifierFlag(const char *startFlags,
718 unsigned flagsLen) {}
719
720 virtual void HandleInvalidObjCModifierFlag(const char *startFlag,
721 unsigned flagLen) {}
722
723 virtual void
725 const char *flagsEnd,
726 const char *conversionPosition) {}
727 // Printf-specific handlers.
728
730 const analyze_printf::PrintfSpecifier &FS, const char *startSpecifier,
731 unsigned specifierLen) {
732 return true;
733 }
734
736 const char *startSpecifier,
737 unsigned specifierLen,
738 const TargetInfo &Target) {
739 return true;
740 }
741
742 /// Handle mask types whose sizes are not between one and eight bytes.
743 virtual void handleInvalidMaskType(StringRef MaskType) {}
744
745 // Scanf-specific handlers.
746
747 virtual bool
749 const char *startSpecifier,
750 unsigned specifierLen) {
751 return true;
752 }
753
755 const char *startSpecifier,
756 unsigned specifierLen) {
757 return true;
758 }
759
760 virtual void HandleIncompleteScanList(const char *start, const char *end) {}
761};
762
763bool ParsePrintfString(FormatStringHandler &H, const char *beg, const char *end,
764 const LangOptions &LO, const TargetInfo &Target,
765 bool isFreeBSDKPrintf);
766
767bool ParseFormatStringHasSArg(const char *beg, const char *end,
768 const LangOptions &LO, const TargetInfo &Target);
769
770bool ParseScanfString(FormatStringHandler &H, const char *beg, const char *end,
771 const LangOptions &LO, const TargetInfo &Target);
772
773/// Return true if the given string has at least one formatting specifier.
774bool parseFormatStringHasFormattingSpecifiers(const char *Begin,
775 const char *End,
776 const LangOptions &LO,
777 const TargetInfo &Target);
778
779} // namespace analyze_format_string
780} // namespace clang
781#endif
*collection of selector each with an associated kind and an ordered *collection of selectors A selector has a kind
ArgType(Kind K=UnknownTy, const char *N=nullptr)
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
Definition ASTContext.h:227
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
A (possibly-)qualified type.
Definition TypeBase.h:937
Exposes information about the current target.
Definition TargetInfo.h:227
static ArgType makePtrdiffT(const ArgType &A)
Create an ArgType which corresponds to the ptrdiff_t/unsigned ptrdiff_t type.
MatchKind
How well a given conversion specifier matches its argument.
@ NoMatch
The conversion specifier and the argument types are incompatible.
@ NoMatchPedantic
The conversion specifier and the argument type are disallowed by the C standard, but are in practice ...
@ Match
The conversion specifier and the argument type are compatible.
@ MatchPromotion
The conversion specifier and the argument type are compatible because of default argument promotions.
@ NoMatchSignedness
The conversion specifier and the argument type have different sign.
@ NoMatchTypeConfusion
The conversion specifier and the argument type are compatible, but still seems likely to be an error.
@ NoMatchPromotionTypeConfusion
The conversion specifier and the argument type are compatible but still seems likely to be an error.
static ArgType PtrTo(const ArgType &A)
Create an ArgType which corresponds to the type pointer to A.
ArgType makeVectorType(ASTContext &C, unsigned NumElts) const
MatchKind matchesArgType(ASTContext &C, const ArgType &other) const
QualType getRepresentativeType(ASTContext &C) const
std::string getRepresentativeTypeName(ASTContext &C) const
ArgType(QualType T, const char *N=nullptr)
static ArgType makeSizeT(const ArgType &A)
Create an ArgType which corresponds to the size_t/ssize_t type.
ArgType(Kind K=UnknownTy, const char *N=nullptr)
MatchKind matchesType(ASTContext &C, QualType argTy) const
std::optional< ConversionSpecifier > getStandardSpecifier() const
ConversionSpecifier(bool isPrintf, const char *pos, Kind k)
static bool namedTypeToLengthModifier(ASTContext &Ctx, 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...
void setFieldWidth(const OptionalAmount &Amt)
const OptionalAmount & getFieldWidth() const
bool hasStandardConversionSpecifier(const LangOptions &LangOpt) const
const LengthModifier & getLengthModifier() const
const OptionalAmount & getVectorNumElts() const
bool hasValidLengthModifier(const TargetInfo &Target, const LangOptions &LO) const
bool UsesPositionalArg
Positional arguments, an IEEE extension: IEEE Std 1003.1, 2004 Edition http://www....
std::optional< LengthModifier > getCorrectedLengthModifier() const
void setVectorNumElts(const OptionalAmount &Amt)
virtual bool HandleInvalidPrintfConversionSpecifier(const analyze_printf::PrintfSpecifier &FS, const char *startSpecifier, unsigned specifierLen)
virtual void HandleObjCFlagsWithNonObjCConversion(const char *flagsStart, const char *flagsEnd, const char *conversionPosition)
virtual void HandleInvalidObjCModifierFlag(const char *startFlag, unsigned flagLen)
virtual void HandleIncompleteScanList(const char *start, const char *end)
virtual void HandleNullChar(const char *nullCharacter)
virtual void handleInvalidMaskType(StringRef MaskType)
Handle mask types whose sizes are not between one and eight bytes.
virtual void HandlePosition(const char *startPos, unsigned posLen)
virtual bool HandlePrintfSpecifier(const analyze_printf::PrintfSpecifier &FS, const char *startSpecifier, unsigned specifierLen, const TargetInfo &Target)
virtual void HandleInvalidPosition(const char *startPos, unsigned posLen, PositionContext p)
virtual void HandleEmptyObjCModifierFlag(const char *startFlags, unsigned flagsLen)
virtual void HandleZeroPosition(const char *startPos, unsigned posLen)
virtual void HandleIncompleteSpecifier(const char *startSpecifier, unsigned specifierLen)
virtual bool HandleScanfSpecifier(const analyze_scanf::ScanfSpecifier &FS, const char *startSpecifier, unsigned specifierLen)
virtual bool HandleInvalidScanfConversionSpecifier(const analyze_scanf::ScanfSpecifier &FS, const char *startSpecifier, unsigned specifierLen)
Represents the length modifier in a format string in scanf/printf.
ArgType getArgType(ASTContext &Ctx) const
OptionalAmount(HowSpecified howSpecified, unsigned amount, const char *amountStart, unsigned amountLength, bool usesPositionalArg)
Class representing optional flags with location and representation information.
OptionalFlag(const char *Representation)
void setPosition(const char *position)
OptionalFlag & operator=(const bool &rhs)
static bool classof(const analyze_format_string::ConversionSpecifier *CS)
const OptionalFlag & isPrivate() const
void setHasAlternativeForm(const char *position)
void setIsSensitive(const char *position)
void setHasSpacePrefix(const char *position)
void setHasThousandsGrouping(const char *position)
const OptionalAmount & getPrecision() const
static PrintfSpecifier Parse(const char *beg, const char *end)
const OptionalFlag & hasSpacePrefix() const
void setIsLeftJustified(const char *position)
bool fixType(QualType QT, const LangOptions &LangOpt, ASTContext &Ctx, bool IsObjCLiteral)
Changes the specifier and length according to a QualType, retaining any flags or options.
const OptionalFlag & isSensitive() const
const OptionalFlag & isLeftJustified() const
const OptionalFlag & hasLeadingZeros() const
const OptionalFlag & hasAlternativeForm() const
void setHasPlusPrefix(const char *position)
void setIsPrivate(const char *position)
const PrintfConversionSpecifier & getConversionSpecifier() const
void setHasLeadingZeros(const char *position)
const OptionalFlag & hasPlusPrefix() const
const OptionalFlag & hasThousandsGrouping() const
ArgType getArgType(ASTContext &Ctx, bool IsObjCLiteral) const
Returns the builtin type that a data argument paired with this format specifier should have.
void setIsPublic(const char *position)
const OptionalFlag & hasObjCTechnicalTerm() const
void setPrecision(const OptionalAmount &Amt)
void setHasObjCTechnicalTerm(const char *position)
const OptionalFlag & isPublic() const
void setConversionSpecifier(const PrintfConversionSpecifier &cs)
ScanfConversionSpecifier(const char *pos, Kind k)
static bool classof(const analyze_format_string::ConversionSpecifier *CS)
static ScanfSpecifier Parse(const char *beg, const char *end)
bool fixType(QualType QT, QualType RawQT, const LangOptions &LangOpt, ASTContext &Ctx)
const OptionalFlag & getSuppressAssignment() const
void setConversionSpecifier(const ScanfConversionSpecifier &cs)
const ScanfConversionSpecifier & getConversionSpecifier() const
void setSuppressAssignment(const char *position)
ArgType getArgType(ASTContext &Ctx) const
Common components of both fprintf and fscanf format strings.
bool parseFormatStringHasFormattingSpecifiers(const char *Begin, const char *End, const LangOptions &LO, const TargetInfo &Target)
Return true if the given string has at least one formatting specifier.
bool ParsePrintfString(FormatStringHandler &H, const char *beg, const char *end, const LangOptions &LO, const TargetInfo &Target, bool isFreeBSDKPrintf)
bool ParseScanfString(FormatStringHandler &H, const char *beg, const char *end, const LangOptions &LO, const TargetInfo &Target)
bool ParseFormatStringHasSArg(const char *beg, const char *end, const LangOptions &LO, const TargetInfo &Target)
Pieces specific to fprintf format strings.
Pieces specific to fscanf format strings.
The JSON file list parser is used to communicate input to InstallAPI.
CanQual< Type > CanQualType
Represents a canonical, potentially-qualified type.
nullptr
This class represents a compute construct, representing a 'Kind' of ‘parallel’, 'serial',...
U cast(CodeGen::Address addr)
Definition Address.h:327
float __ovld __cnfn length(float)
Return the length of vector p, i.e., sqrt(p.x2 + p.y 2 + ...)
#define false
Definition stdbool.h:26
#define true
Definition stdbool.h:25