]> granicus.if.org Git - clang/commitdiff
Replace a hack to handle NSLog/NSLogv in sema by declaring them as Library Builtins.
authorJean-Daniel Dupas <devlists@shadowlab.org>
Tue, 24 Jan 2012 22:32:46 +0000 (22:32 +0000)
committerJean-Daniel Dupas <devlists@shadowlab.org>
Tue, 24 Jan 2012 22:32:46 +0000 (22:32 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@148873 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/Basic/Builtins.def
lib/Sema/SemaDecl.cpp
test/SemaObjC/builtin_objc_nslog.m [new file with mode: 0644]

index 60ef5384cca351e08811d1d6518e2a941cf5766f..d49d611fd1a6525412d22e4f51a89eaf335252e9 100644 (file)
@@ -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)
index a84612edfc0b1e9f35034834e2fab645d944f611..e7ff5c5400adb1cae09776b86095604bc6a5bd2a 100644 (file)
@@ -7420,10 +7420,16 @@ void Sema::AddKnownFunctionAttributes(FunctionDecl *FD) {
     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)) {
@@ -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<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>())
diff --git a/test/SemaObjC/builtin_objc_nslog.m b/test/SemaObjC/builtin_objc_nslog.m
new file mode 100644 (file)
index 0000000..ac33050
--- /dev/null
@@ -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'}}
+}