From: Jean-Daniel Dupas Date: Tue, 24 Jan 2012 22:32:46 +0000 (+0000) Subject: Replace a hack to handle NSLog/NSLogv in sema by declaring them as Library Builtins. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=1acbe5e65631c7b52fa559df2bdcfdf76d4c410a;p=clang Replace a hack to handle NSLog/NSLogv in sema by declaring them as Library Builtins. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@148873 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/Basic/Builtins.def b/include/clang/Basic/Builtins.def index 60ef5384cc..d49d611fd1 100644 --- a/include/clang/Basic/Builtins.def +++ b/include/clang/Basic/Builtins.def @@ -756,6 +756,11 @@ LIBBUILTIN(objc_sync_exit, "iG", "f", "objc/objc-sync.h", OBJC_LANG) BUILTIN(__builtin_objc_memmove_collectable, "v*v*vC*z", "nF") +// void NSLog(NSString *fmt, ...) +LIBBUILTIN(NSLog, "vG.", "fp:0:", "Foundation/NSObjCRuntime.h", OBJC_LANG) +// void NSLogv(NSString *fmt, va_list args) +LIBBUILTIN(NSLogv, "vGa", "fP:0:", "Foundation/NSObjCRuntime.h", OBJC_LANG) + // Builtin math library functions LIBBUILTIN(pow, "ddd", "fe", "math.h", ALL_LANGUAGES) LIBBUILTIN(powl, "LdLdLd", "fe", "math.h", ALL_LANGUAGES) diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp index a84612edfc..e7ff5c5400 100644 --- a/lib/Sema/SemaDecl.cpp +++ b/lib/Sema/SemaDecl.cpp @@ -7420,10 +7420,16 @@ void Sema::AddKnownFunctionAttributes(FunctionDecl *FD) { unsigned FormatIdx; bool HasVAListArg; if (Context.BuiltinInfo.isPrintfLike(BuiltinID, FormatIdx, HasVAListArg)) { - if (!FD->getAttr()) + if (!FD->getAttr()) { + const char *fmt = "printf"; + unsigned int NumParams = FD->getNumParams(); + if (FormatIdx < NumParams && // NumParams may be 0 (e.g. vfprintf) + FD->getParamDecl(FormatIdx)->getType()->isObjCObjectPointerType()) + fmt = "NSString"; FD->addAttr(::new (Context) FormatAttr(FD->getLocation(), Context, - "printf", FormatIdx+1, + fmt, FormatIdx+1, HasVAListArg ? 0 : FormatIdx+2)); + } } if (Context.BuiltinInfo.isScanfLike(BuiltinID, FormatIdx, HasVAListArg)) { @@ -7464,16 +7470,7 @@ void Sema::AddKnownFunctionAttributes(FunctionDecl *FD) { } else return; - if (Name->isStr("NSLog") || Name->isStr("NSLogv")) { - // FIXME: NSLog and NSLogv should be target specific - if (const FormatAttr *Format = FD->getAttr()) { - // FIXME: We known better than our headers. - const_cast(Format)->setType(Context, "printf"); - } else - FD->addAttr(::new (Context) FormatAttr(FD->getLocation(), Context, - "printf", 1, - Name->isStr("NSLogv") ? 0 : 2)); - } else if (Name->isStr("asprintf") || Name->isStr("vasprintf")) { + if (Name->isStr("asprintf") || Name->isStr("vasprintf")) { // FIXME: asprintf and vasprintf aren't C99 functions. Should they be // target-specific builtins, perhaps? if (!FD->getAttr()) diff --git a/test/SemaObjC/builtin_objc_nslog.m b/test/SemaObjC/builtin_objc_nslog.m new file mode 100644 index 0000000000..ac33050040 --- /dev/null +++ b/test/SemaObjC/builtin_objc_nslog.m @@ -0,0 +1,13 @@ +// RUN: %clang_cc1 -x objective-c %s -fsyntax-only -verify + +#include + +void f1(id arg) { + NSLog(@"%@", arg); // expected-warning {{implicitly declaring C library function 'NSLog' with type 'void (id, ...)'}} \ + // expected-note {{please include the header or explicitly provide a declaration for 'NSLog'}} +} + +void f2(id str, va_list args) { + NSLogv(@"%@", args); // expected-warning {{implicitly declaring C library function 'NSLogv' with type 'void (id, __va_list_tag *)'}} \ + // expected-note {{please include the header or explicitly provide a declaration for 'NSLogv'}} +}