]> granicus.if.org Git - clang/commitdiff
objc_gc wants a pointer type, not a function type; give it a more appropriate
authorJohn McCall <rjmccall@apple.com>
Tue, 8 Mar 2011 04:17:03 +0000 (04:17 +0000)
committerJohn McCall <rjmccall@apple.com>
Tue, 8 Mar 2011 04:17:03 +0000 (04:17 +0000)
diagnostic.  Also, these attributes are commonly written with macros which we
actually pre-define, so instead of expanding the macro location, refer to the
instantiation location and name it using the macro loc.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@127219 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/Basic/DiagnosticSemaKinds.td
lib/Sema/SemaType.cpp
test/SemaObjC/attr-objc-gc.m

index 7cd6d9ed7f52e6000ccf3188e1bc80dd80d50840..e86296037921a9c4d11d4c8bbbaa355d67de4435 100644 (file)
@@ -1115,7 +1115,9 @@ def err_attribute_wrong_decl_type : Error<
   "classes and virtual methods|functions, methods, and parameters|"
   "classes|virtual methods|class members|variables|methods}1">;
 def warn_function_attribute_wrong_type : Warning<
-  "%0 only applies to function types; type here is %1">;
+  "'%0' only applies to function types; type here is %1">;
+def warn_pointer_attribute_wrong_type : Warning<
+  "'%0' only applies to pointer types; type here is %1">;
 def warn_gnu_inline_attribute_requires_inline : Warning<
   "'gnu_inline' attribute requires function to be marked 'inline',"
   " attribute ignored">;
index 9d973237ddc2edab99d56a65efc9a05f28e54c9f..772a55754594ff66b232bccc2cee96b7d27a263f 100644 (file)
@@ -22,6 +22,7 @@
 #include "clang/AST/Expr.h"
 #include "clang/Basic/PartialDiagnostic.h"
 #include "clang/Basic/TargetInfo.h"
+#include "clang/Lex/Preprocessor.h"
 #include "clang/Sema/DeclSpec.h"
 #include "llvm/ADT/SmallPtrSet.h"
 #include "llvm/Support/ErrorHandling.h"
@@ -70,6 +71,42 @@ static bool isOmittedBlockReturnType(const Declarator &D) {
   return false;
 }
 
+/// diagnoseBadTypeAttribute - Diagnoses a type attribute which
+/// doesn't apply to the given type.
+static void diagnoseBadTypeAttribute(Sema &S, const AttributeList &attr,
+                                     QualType type) {
+  bool useInstantiationLoc = false;
+
+  unsigned diagID = 0;
+  switch (attr.getKind()) {
+  case AttributeList::AT_objc_gc:
+    diagID = diag::warn_pointer_attribute_wrong_type;
+    useInstantiationLoc = true;
+    break;
+
+  default:
+    // Assume everything else was a function attribute.
+    diagID = diag::warn_function_attribute_wrong_type;
+    break;
+  }
+
+  SourceLocation loc = attr.getLoc();
+  llvm::StringRef name = attr.getName()->getName();
+
+  // The GC attributes are usually written with macros;  special-case them.
+  if (useInstantiationLoc && loc.isMacroID() && attr.getParameterName()) {
+    SourceLocation instLoc = S.getSourceManager().getInstantiationLoc(loc);
+    llvm::StringRef macro = S.getPreprocessor().getSpelling(instLoc);
+    if ((macro == "__strong" && attr.getParameterName()->isStr("strong")) ||
+        (macro == "__weak" && attr.getParameterName()->isStr("weak"))) {
+      loc = instLoc;
+      name = macro;
+    }
+  }
+
+  S.Diag(loc, diagID) << name << type;
+}
+
 // objc_gc applies to Objective-C pointers or, otherwise, to the
 // smallest available pointer type (i.e. 'void*' in 'void**').
 #define OBJC_POINTER_TYPE_ATTRS_CASELIST \
@@ -162,11 +199,8 @@ namespace {
     void diagnoseIgnoredTypeAttrs(QualType type) const {
       for (llvm::SmallVectorImpl<AttributeList*>::const_iterator
              i = ignoredTypeAttrs.begin(), e = ignoredTypeAttrs.end();
-           i != e; ++i) {
-        AttributeList &attr = **i;
-        getSema().Diag(attr.getLoc(), diag::warn_function_attribute_wrong_type)
-          << attr.getName() << type;
-      }
+           i != e; ++i)
+        diagnoseBadTypeAttribute(getSema(), **i, type);
     }
 
     ~TypeProcessingState() {
@@ -287,9 +321,8 @@ static void distributeObjCPointerTypeAttr(TypeProcessingState &state,
     }
   }
  error:
-  
-  state.getSema().Diag(attr.getLoc(), diag::warn_function_attribute_wrong_type)
-    << attr.getName() << type;
+
+  diagnoseBadTypeAttribute(state.getSema(), attr, type);
 }
 
 /// Distribute an objc_gc type attribute that was written on the
@@ -374,8 +407,7 @@ static void distributeFunctionTypeAttr(TypeProcessingState &state,
     }
   }
   
-  state.getSema().Diag(attr.getLoc(), diag::warn_function_attribute_wrong_type)
-    << attr.getName() << type;
+  diagnoseBadTypeAttribute(state.getSema(), attr, type);
 }
 
 /// Try to distribute a function type attribute to the innermost
index fd818557f5e72c55bb5047928e769b9533e7e501..cfe59516ee7d47560ecf79d1f8f019abd4243cb3 100644 (file)
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fsyntax-only -verify %s
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fsyntax-only -verify %s
 static id __attribute((objc_gc(weak))) a;
 static id __attribute((objc_gc(strong))) b;
 
@@ -6,3 +6,7 @@ static id __attribute((objc_gc())) c; // expected-error{{'objc_gc' attribute req
 static id __attribute((objc_gc(123))) d; // expected-error{{'objc_gc' attribute requires parameter 1 to be a string}}
 static id __attribute((objc_gc(foo, 456))) e; // expected-error{{attribute takes one argument}}
 static id __attribute((objc_gc(hello))) f; // expected-warning{{'objc_gc' attribute argument not supported: 'hello'}}
+
+static int __attribute__((objc_gc(weak))) g; // expected-warning {{'objc_gc' only applies to pointer types; type here is 'int'}}
+
+static __weak int h; // expected-warning {{'__weak' only applies to pointer types; type here is 'int'}}