diff options
author | Ted Kremenek <kremenek@apple.com> | 2015-07-02 05:39:16 +0000 |
---|---|---|
committer | Ted Kremenek <kremenek@apple.com> | 2015-07-02 05:39:16 +0000 |
commit | 2b4177190923be8cb459274f25a25bb07913e760 (patch) | |
tree | c1f150624f95956aad8b35f2595d87aa52bd5953 /clang/lib/Sema/SemaChecking.cpp | |
parent | 7a1ef0ddca23cfe197caf5b3336fa8076ee2a075 (diff) | |
download | bcm5719-llvm-2b4177190923be8cb459274f25a25bb07913e760.tar.gz bcm5719-llvm-2b4177190923be8cb459274f25a25bb07913e760.zip |
Parse 'technical term' format specifier.
Objective-C format strings now support modifier flags
that can be attached to a '@' conversion. Currently
the only one supported, as of iOS 9 and OS X 10.11,
is the new "technical term", denoted by the flag "tt",
for example:
%[tt]@
instead of just:
%@
The 'tt' stands for "technical term", which is used
by the string-localization facilities on Darwin to
add the appropriate spacing or quotation depending
the language locale.
Implements <rdar://problem/20374720>.
llvm-svn: 241243
Diffstat (limited to 'clang/lib/Sema/SemaChecking.cpp')
-rw-r--r-- | clang/lib/Sema/SemaChecking.cpp | 47 |
1 files changed, 46 insertions, 1 deletions
diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp index 870da782b97..5737e8338ff 100644 --- a/clang/lib/Sema/SemaChecking.cpp +++ b/clang/lib/Sema/SemaChecking.cpp @@ -3572,8 +3572,18 @@ public: const char *startSpecifier, unsigned specifierLen); bool checkForCStrMembers(const analyze_printf::ArgType &AT, const Expr *E); + + void HandleEmptyObjCModifierFlag(const char *startFlag, + unsigned flagLen) override; -}; + void HandleInvalidObjCModifierFlag(const char *startFlag, + unsigned flagLen) override; + + void HandleObjCFlagsWithNonObjCConversion(const char *flagsStart, + const char *flagsEnd, + const char *conversionPosition) + override; +}; } bool CheckPrintfHandler::HandleInvalidPrintfConversionSpecifier( @@ -3693,6 +3703,41 @@ void CheckPrintfHandler::HandleIgnoredFlag( getSpecifierRange(ignoredFlag.getPosition(), 1))); } +// void EmitFormatDiagnostic(PartialDiagnostic PDiag, SourceLocation StringLoc, +// bool IsStringLocation, Range StringRange, +// ArrayRef<FixItHint> Fixit = None); + +void CheckPrintfHandler::HandleEmptyObjCModifierFlag(const char *startFlag, + unsigned flagLen) { + // Warn about an empty flag. + EmitFormatDiagnostic(S.PDiag(diag::warn_printf_empty_objc_flag), + getLocationOfByte(startFlag), + /*IsStringLocation*/true, + getSpecifierRange(startFlag, flagLen)); +} + +void CheckPrintfHandler::HandleInvalidObjCModifierFlag(const char *startFlag, + unsigned flagLen) { + // Warn about an invalid flag. + auto Range = getSpecifierRange(startFlag, flagLen); + StringRef flag(startFlag, flagLen); + EmitFormatDiagnostic(S.PDiag(diag::warn_printf_invalid_objc_flag) << flag, + getLocationOfByte(startFlag), + /*IsStringLocation*/true, + Range, FixItHint::CreateRemoval(Range)); +} + +void CheckPrintfHandler::HandleObjCFlagsWithNonObjCConversion( + const char *flagsStart, const char *flagsEnd, const char *conversionPosition) { + // Warn about using '[...]' without a '@' conversion. + auto Range = getSpecifierRange(flagsStart, flagsEnd - flagsStart + 1); + auto diag = diag::warn_printf_ObjCflags_without_ObjCConversion; + EmitFormatDiagnostic(S.PDiag(diag) << StringRef(conversionPosition, 1), + getLocationOfByte(conversionPosition), + /*IsStringLocation*/true, + Range, FixItHint::CreateRemoval(Range)); +} + // Determines if the specified is a C++ class or struct containing // a member with the specified name and kind (e.g. a CXXMethodDecl named // "c_str()"). |