Index: include/clang/Basic/Builtins.def
===================================================================
--- include/clang/Basic/Builtins.def	(revision 148635)
+++ include/clang/Basic/Builtins.def	(working copy)
@@ -728,34 +728,39 @@
 LIBBUILTIN(objc_enumerationMutation, "vG", "f", "objc/runtime.h", OBJC_LANG)
 
 // id objc_read_weak(id *location)
-LIBBUILTIN(objc_read_weak, "GG*", "f", "/objc/objc-auto.h", OBJC_LANG)
+LIBBUILTIN(objc_read_weak, "GG*", "f", "objc/objc-auto.h", OBJC_LANG)
 // id objc_assign_weak(id value, id *location)
-LIBBUILTIN(objc_assign_weak, "GGG*", "f", "/objc/objc-auto.h", OBJC_LANG)
+LIBBUILTIN(objc_assign_weak, "GGG*", "f", "objc/objc-auto.h", OBJC_LANG)
 // id objc_assign_ivar(id value, id dest, ptrdiff_t offset)
-LIBBUILTIN(objc_assign_ivar, "GGGY", "f", "/objc/objc-auto.h", OBJC_LANG)
+LIBBUILTIN(objc_assign_ivar, "GGGY", "f", "objc/objc-auto.h", OBJC_LANG)
 // id objc_assign_global(id val, id *dest)
-LIBBUILTIN(objc_assign_global, "GGG*", "f", "/objc/objc-auto.h", OBJC_LANG)
+LIBBUILTIN(objc_assign_global, "GGG*", "f", "objc/objc-auto.h", OBJC_LANG)
 // id objc_assign_strongCast(id val, id *dest
-LIBBUILTIN(objc_assign_strongCast, "GGG*", "f", "/objc/objc-auto.h", OBJC_LANG)
+LIBBUILTIN(objc_assign_strongCast, "GGG*", "f", "objc/objc-auto.h", OBJC_LANG)
 
 // id objc_exception_extract(void *localExceptionData)
-LIBBUILTIN(objc_exception_extract, "Gv*", "f", "/objc/objc-exception.h", OBJC_LANG)
+LIBBUILTIN(objc_exception_extract, "Gv*", "f", "objc/objc-exception.h", OBJC_LANG)
 // void objc_exception_try_enter(void *localExceptionData)
-LIBBUILTIN(objc_exception_try_enter, "vv*", "f", "/objc/objc-exception.h", OBJC_LANG)
+LIBBUILTIN(objc_exception_try_enter, "vv*", "f", "objc/objc-exception.h", OBJC_LANG)
 // void objc_exception_try_exit(void *localExceptionData)
-LIBBUILTIN(objc_exception_try_exit, "vv*", "f", "/objc/objc-exception.h", OBJC_LANG)
+LIBBUILTIN(objc_exception_try_exit, "vv*", "f", "objc/objc-exception.h", OBJC_LANG)
 // int objc_exception_match(Class exceptionClass, id exception)
-LIBBUILTIN(objc_exception_match, "iGG", "f", "/objc/objc-exception.h", OBJC_LANG)
+LIBBUILTIN(objc_exception_match, "iGG", "f", "objc/objc-exception.h", OBJC_LANG)
 // void objc_exception_throw(id exception)
-LIBBUILTIN(objc_exception_throw, "vG", "f", "/objc/objc-exception.h", OBJC_LANG)
+LIBBUILTIN(objc_exception_throw, "vG", "f", "objc/objc-exception.h", OBJC_LANG)
 
 // int objc_sync_enter(id obj)
-LIBBUILTIN(objc_sync_enter, "iG", "f", "/objc/objc-sync.h", OBJC_LANG)
+LIBBUILTIN(objc_sync_enter, "iG", "f", "objc/objc-sync.h", OBJC_LANG)
 // int objc_sync_exit(id obj)
-LIBBUILTIN(objc_sync_exit, "iG", "f", "/objc/objc-sync.h", OBJC_LANG)
+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)
Index: lib/Sema/SemaDecl.cpp
===================================================================
--- lib/Sema/SemaDecl.cpp	(revision 148635)
+++ lib/Sema/SemaDecl.cpp	(working copy)
@@ -7419,10 +7419,16 @@
     unsigned FormatIdx;
     bool HasVAListArg;
     if (Context.BuiltinInfo.isPrintfLike(BuiltinID, FormatIdx, HasVAListArg)) {
-      if (!FD->getAttr<FormatAttr>())
+      if (!FD->getAttr<FormatAttr>()) {
+        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)) {
@@ -7463,16 +7469,7 @@
   } else
     return;
 
-  if (Name->isStr("NSLog") || Name->isStr("NSLogv")) {
-    // FIXME: NSLog and NSLogv should be target specific
-    if (const FormatAttr *Format = FD->getAttr<FormatAttr>()) {
-      // FIXME: We known better than our headers.
-      const_cast<FormatAttr *>(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<FormatAttr>())
Index: test/SemaObjC/builtin_objc_lib_functions.m
===================================================================
--- test/SemaObjC/builtin_objc_lib_functions.m	(revision 148635)
+++ test/SemaObjC/builtin_objc_lib_functions.m	(working copy)
@@ -20,10 +20,10 @@
 
 id f5(id val, id *dest) {
   return objc_assign_strongCast(val, dest); // expected-warning {{implicitly declaring C library function 'objc_assign_strongCast' with type 'id (id, id *)'}} \
-					    // expected-note {{please include the header </objc/objc-auto.h> or explicitly provide a declaration for 'objc_assign_strongCast'}}
+					    // expected-note {{please include the header <objc/objc-auto.h> or explicitly provide a declaration for 'objc_assign_strongCast'}}
 }
 
 int f6(Class exceptionClass, id exception) {
   return objc_exception_match(exceptionClass, exception); // expected-warning {{implicitly declaring C library function 'objc_exception_match' with type 'int (id, id)'}} \
-  							  // expected-note {{please include the header </objc/objc-exception.h> or explicitly provide a declaration for 'objc_exception_match'}}
+  							  // expected-note {{please include the header <objc/objc-exception.h> or explicitly provide a declaration for 'objc_exception_match'}}
 }
Index: test/SemaObjC/builtin_objc_nslog.m
===================================================================
--- test/SemaObjC/builtin_objc_nslog.m	(revision 0)
+++ test/SemaObjC/builtin_objc_nslog.m	(working copy)
@@ -0,0 +1,13 @@
+// RUN: %clang_cc1 -x objective-c %s -fsyntax-only -verify
+
+#include <stdarg.h>
+
+void f1(id arg) {
+  NSLog(@"%@", arg); // expected-warning {{implicitly declaring C library function 'NSLog' with type 'void (id, ...)'}} \
+  // expected-note {{please include the header <Foundation/NSObjCRuntime.h> 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 <Foundation/NSObjCRuntime.h> or explicitly provide a declaration for 'NSLogv'}}
+}

Property changes on: test/SemaObjC/builtin_objc_nslog.m
___________________________________________________________________
Added: svn:mime-type
## -0,0 +1 ##
+text/plain;charset=utf-8
Added: svn:eol-style
## -0,0 +1 ##
+native
