[cfe-commits] r56640 - in /cfe/trunk: lib/Sema/SemaDeclAttr.cpp lib/Sema/SemaDeclObjC.cpp test/SemaObjC/method-attributes.m

Daniel Dunbar daniel at zuster.org
Thu Sep 25 21:12:30 PDT 2008


Author: ddunbar
Date: Thu Sep 25 23:12:28 2008
New Revision: 56640

URL: http://llvm.org/viewvc/llvm-project?rev=56640&view=rev
Log:
Sema support for format and noreturn attributes on Objective-C methods.

Added:
    cfe/trunk/test/SemaObjC/method-attributes.m
Modified:
    cfe/trunk/lib/Sema/SemaDeclAttr.cpp
    cfe/trunk/lib/Sema/SemaDeclObjC.cpp

Modified: cfe/trunk/lib/Sema/SemaDeclAttr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclAttr.cpp?rev=56640&r1=56639&r2=56640&view=diff

==============================================================================
--- cfe/trunk/lib/Sema/SemaDeclAttr.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDeclAttr.cpp Thu Sep 25 23:12:28 2008
@@ -45,6 +45,40 @@
   return 0;
 }
 
+// FIXME: We should provide an abstraction around a method or function
+// to provide the following bits of information.
+
+/// isFunctionOrMethod - Return true if the given decl is a (non-K&R)
+/// function or an Objective-C method.
+static bool isFunctionOrMethod(Decl *d) {
+  return getFunctionProto(d) || isa<ObjCMethodDecl>(d);
+
+}
+
+static unsigned getFunctionOrMethodNumArgs(Decl *d) {
+  if (const FunctionTypeProto *proto = getFunctionProto(d)) {
+    return proto->getNumArgs();
+  } else {
+    return cast<ObjCMethodDecl>(d)->getNumParams();
+  }
+}
+
+static QualType getFunctionOrMethodArgType(Decl *d, unsigned Idx) {
+  if (const FunctionTypeProto *proto = getFunctionProto(d)) {
+    return proto->getArgType(Idx);
+  } else {
+    return cast<ObjCMethodDecl>(d)->getParamDecl(Idx)->getType();
+  }
+}
+
+static bool isFunctionOrMethodVariadic(Decl *d) {
+  if (const FunctionTypeProto *proto = getFunctionProto(d)) {
+    return proto->isVariadic();
+  } else {
+    return cast<ObjCMethodDecl>(d)->isVariadic();
+  }
+}
+
 static inline bool isNSStringType(QualType T, ASTContext &Ctx) {
   const PointerType *PT = T->getAsPointerType();
   if (!PT)
@@ -360,8 +394,7 @@
     return;
   }
   
-  FunctionDecl *Fn = dyn_cast<FunctionDecl>(d);
-  if (!Fn) {
+  if (!isa<FunctionDecl>(d) && !isa<ObjCMethodDecl>(d)) {
     S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type,
            "noreturn", "function");
     return;
@@ -637,9 +670,7 @@
 
   // GCC ignores the format attribute on K&R style function
   // prototypes, so we ignore it as well
-  const FunctionTypeProto *proto = getFunctionProto(d);
-
-  if (!proto) {
+  if (!isFunctionOrMethod(d)) {
     S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type,
            "format", "function");
     return;
@@ -648,7 +679,7 @@
   // FIXME: in C++ the implicit 'this' function parameter also counts.
   // this is needed in order to be compatible with GCC
   // the index must start in 1 and the limit is numargs+1
-  unsigned NumArgs  = proto->getNumArgs();
+  unsigned NumArgs  = getFunctionOrMethodNumArgs(d);
   unsigned FirstIdx = 1;
 
   const char *Format = Attr.getParameterName()->getName();
@@ -703,7 +734,7 @@
   unsigned ArgIdx = Idx.getZExtValue() - 1;
   
   // make sure the format string is really a string
-  QualType Ty = proto->getArgType(ArgIdx);
+  QualType Ty = getFunctionOrMethodArgType(d, ArgIdx);
 
   if (is_CFString) {
     if (!isCFStringType(Ty, S.Context)) {
@@ -741,7 +772,7 @@
 
   // check if the function is variadic if the 3rd argument non-zero
   if (FirstArg != 0) {
-    if (proto->isVariadic()) {
+    if (isFunctionOrMethodVariadic(d)) {
       ++NumArgs; // +1 for ...
     } else {
       S.Diag(d->getLocation(), diag::err_format_attribute_requires_variadic);

Modified: cfe/trunk/lib/Sema/SemaDeclObjC.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclObjC.cpp?rev=56640&r1=56639&r2=56640&view=diff

==============================================================================
--- cfe/trunk/lib/Sema/SemaDeclObjC.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDeclObjC.cpp Thu Sep 25 23:12:28 2008
@@ -978,8 +978,6 @@
                            MethodDeclKind == tok::objc_optional ? 
                            ObjCMethodDecl::Optional : 
                            ObjCMethodDecl::Required);
-  if (AttrList)
-    ProcessDeclAttributeList(ObjCMethod, AttrList);
   
   llvm::SmallVector<ParmVarDecl*, 16> Params;
   
@@ -1004,6 +1002,9 @@
   ObjCMethod->setObjCDeclQualifier(
     CvtQTToAstBitMask(ReturnQT.getObjCDeclQualifier()));
   const ObjCMethodDecl *PrevMethod = 0;
+
+  if (AttrList)
+    ProcessDeclAttributeList(ObjCMethod, AttrList);
  
   // For implementations (which can be very "coarse grain"), we add the 
   // method now. This allows the AST to implement lookup methods that work 

Added: cfe/trunk/test/SemaObjC/method-attributes.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaObjC/method-attributes.m?rev=56640&view=auto

==============================================================================
--- cfe/trunk/test/SemaObjC/method-attributes.m (added)
+++ cfe/trunk/test/SemaObjC/method-attributes.m Thu Sep 25 23:12:28 2008
@@ -0,0 +1,8 @@
+// RUN: clang -fsyntax-only %s
+
+ at class NSString;
+
+ at interface A
+-t1 __attribute__((noreturn));
+- (NSString *)stringByAppendingFormat:(NSString *)format, ... __attribute__((format(__NSString__, 1, 2)));
+ at end





More information about the cfe-commits mailing list