mirror of https://github.com/microsoft/clang.git
[Objective-C]. Provide a new formatting kind, "os_trace" which
can take a "const char*" format but supports standard printf and CF/NS types . rdar://19904147 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@230109 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
59fc8c4fb6
commit
4124d39ea0
|
@ -8592,6 +8592,7 @@ public:
|
|||
FST_Strfmon,
|
||||
FST_Kprintf,
|
||||
FST_FreeBSDKPrintf,
|
||||
FST_OSTrace,
|
||||
FST_Unknown
|
||||
};
|
||||
static FormatStringType GetFormatStringType(const FormatAttr *Format);
|
||||
|
|
|
@ -2681,6 +2681,7 @@ Sema::FormatStringType Sema::GetFormatStringType(const FormatAttr *Format) {
|
|||
.Case("strfmon", FST_Strfmon)
|
||||
.Cases("kprintf", "cmn_err", "vcmn_err", "zcmn_err", FST_Kprintf)
|
||||
.Case("freebsd_kprintf", FST_FreeBSDKPrintf)
|
||||
.Case("os_trace", FST_OSTrace)
|
||||
.Default(FST_Unknown);
|
||||
}
|
||||
|
||||
|
@ -4123,9 +4124,9 @@ void Sema::CheckFormatString(const StringLiteral *FExpr,
|
|||
}
|
||||
|
||||
if (Type == FST_Printf || Type == FST_NSString ||
|
||||
Type == FST_FreeBSDKPrintf) {
|
||||
Type == FST_FreeBSDKPrintf || Type == FST_OSTrace) {
|
||||
CheckPrintfHandler H(*this, FExpr, OrigFormatExpr, firstDataArg,
|
||||
numDataArgs, (Type == FST_NSString),
|
||||
numDataArgs, (Type == FST_NSString || Type == FST_OSTrace),
|
||||
Str, HasVAListArg, Args, format_idx,
|
||||
inFunctionCall, CallType, CheckedVarArgs);
|
||||
|
||||
|
|
|
@ -2494,6 +2494,7 @@ static FormatAttrKind getFormatAttrKind(StringRef Format) {
|
|||
.Cases("cmn_err", "vcmn_err", "zcmn_err", SupportedFormat)
|
||||
.Case("kprintf", SupportedFormat) // OpenBSD.
|
||||
.Case("freebsd_kprintf", SupportedFormat) // FreeBSD.
|
||||
.Case("os_trace", SupportedFormat)
|
||||
|
||||
.Cases("gcc_diag", "gcc_cdiag", "gcc_cxxdiag", "gcc_tdiag", IgnoredFormat)
|
||||
.Default(InvalidFormat);
|
||||
|
|
|
@ -0,0 +1,54 @@
|
|||
// RUN: %clang_cc1 -Wcstring-format-directive -verify -fsyntax-only %s
|
||||
// rdar://19904147
|
||||
|
||||
typedef __builtin_va_list __darwin_va_list;
|
||||
typedef __builtin_va_list va_list;
|
||||
|
||||
va_list argList;
|
||||
|
||||
typedef const struct __CFString * CFStringRef;
|
||||
typedef struct __CFString * CFMutableStringRef;
|
||||
typedef const struct __CFAllocator * CFAllocatorRef;
|
||||
|
||||
|
||||
typedef const struct __CFDictionary * CFDictionaryRef;
|
||||
|
||||
CFStringRef CFSTR ( const char *cStr );
|
||||
|
||||
|
||||
extern
|
||||
CFStringRef CStringCreateWithFormat(CFAllocatorRef alloc, CFDictionaryRef formatOptions, const char* format, ...) __attribute__((format(os_trace, 3, 4)));
|
||||
|
||||
extern
|
||||
CFStringRef CStringCreateWithFormatAndArguments(CFAllocatorRef alloc, CFDictionaryRef formatOptions, const char* format, va_list arguments) __attribute__((format(os_trace, 3, 0)));
|
||||
|
||||
extern
|
||||
void CStringAppendFormat(CFMutableStringRef theString, CFDictionaryRef formatOptions, const char* format, ...) __attribute__((format(os_trace, 3, 4)));
|
||||
|
||||
extern
|
||||
void CStringAppendFormatAndArguments(CFMutableStringRef theString, CFDictionaryRef formatOptions, const char* format, va_list arguments) __attribute__((format(os_trace, 3, 0)));
|
||||
|
||||
void Test1(va_list argList) {
|
||||
CFAllocatorRef alloc;
|
||||
CStringCreateWithFormatAndArguments (alloc, 0, "%s\n", argList);
|
||||
CStringAppendFormatAndArguments ((CFMutableStringRef)@"AAAA", 0, "Hello %s there %d\n", argList);
|
||||
CStringCreateWithFormatAndArguments (alloc, 0, "%c\n", argList);
|
||||
CStringAppendFormatAndArguments ((CFMutableStringRef)@"AAAA", 0, "%d\n", argList);
|
||||
}
|
||||
|
||||
extern void MyOSLog(const char* format, ...) __attribute__((format(os_trace, 1, 2)));
|
||||
extern void MyFStringCreateWithFormat(const char *format, ...) __attribute__((format(os_trace, 1, 2)));
|
||||
extern void XMyOSLog(int, const char* format, ...) __attribute__((format(os_trace, 2, 3)));
|
||||
extern void os_trace(const char *format, ...) __attribute__((format(os_trace, 1, 2)));
|
||||
|
||||
void Test2() {
|
||||
MyOSLog("%s\n", "Hello");
|
||||
|
||||
MyFStringCreateWithFormat("%s", "Hello");
|
||||
XMyOSLog(4, "%s\n", "Hello");
|
||||
|
||||
os_trace("testing %@, %s, %d, %@, %m", CFSTR("object"), "string", 3, "it"); // expected-warning {{format specifies type 'id' but the argument has type 'char *'}}
|
||||
|
||||
os_trace("testing %@, %s, %d, %@, %m", CFSTR("object"), "string", 3, @"ok");
|
||||
}
|
||||
|
Loading…
Reference in New Issue