[cfe-commits] r57121 - in /cfe/trunk: include/clang/Basic/DiagnosticKinds.def include/clang/Parse/AttributeList.h lib/Parse/AttributeList.cpp lib/Sema/SemaDeclAttr.cpp test/Sema/sentinel-attribute.c

Anders Carlsson andersca at mac.com
Sun Oct 5 11:06:00 PDT 2008


Author: andersca
Date: Sun Oct  5 13:05:59 2008
New Revision: 57121

URL: http://llvm.org/viewvc/llvm-project?rev=57121&view=rev
Log:
Add parsing of the sentinel attribute. Still need to create the attribute.

Added:
    cfe/trunk/test/Sema/sentinel-attribute.c
Modified:
    cfe/trunk/include/clang/Basic/DiagnosticKinds.def
    cfe/trunk/include/clang/Parse/AttributeList.h
    cfe/trunk/lib/Parse/AttributeList.cpp
    cfe/trunk/lib/Sema/SemaDeclAttr.cpp

Modified: cfe/trunk/include/clang/Basic/DiagnosticKinds.def
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticKinds.def?rev=57121&r1=57120&r2=57121&view=diff

==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticKinds.def (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticKinds.def Sun Oct  5 13:05:59 2008
@@ -733,6 +733,12 @@
 DIAG(warn_transparent_union_nonpointer, WARNING,
   "'transparent_union' attribute support incomplete; only supported for"
   "pointer unions")
+DIAG(warn_attribute_sentinel_not_variadic, WARNING,
+  "'sentinel' attribute only supported for variadic functions")
+DIAG(err_attribute_sentinel_less_than_zero, ERROR,
+  "'sentinel' parameter 1 less than zero")
+DIAG(err_attribute_sentinel_not_zero_or_one, ERROR,
+  "'sentinel' parameter 2 not 0 or 1")
   
 // Clang-Specific Attributes
 DIAG(err_attribute_iboutlet_non_ivar, ERROR,

Modified: cfe/trunk/include/clang/Parse/AttributeList.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Parse/AttributeList.h?rev=57121&r1=57120&r2=57121&view=diff

==============================================================================
--- cfe/trunk/include/clang/Parse/AttributeList.h (original)
+++ cfe/trunk/include/clang/Parse/AttributeList.h Sun Oct  5 13:05:59 2008
@@ -72,6 +72,7 @@
     AT_weak,
     AT_objc_gc,
     AT_blocks,
+    AT_sentinel,
     UnknownAttribute
   };
   

Modified: cfe/trunk/lib/Parse/AttributeList.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/AttributeList.cpp?rev=57121&r1=57120&r2=57121&view=diff

==============================================================================
--- cfe/trunk/lib/Parse/AttributeList.cpp (original)
+++ cfe/trunk/lib/Parse/AttributeList.cpp Sun Oct  5 13:05:59 2008
@@ -80,6 +80,7 @@
     if (!memcmp(Str, "noinline", 8)) return AT_noinline;
     if (!memcmp(Str, "fastcall", 8)) return AT_fastcall;
     if (!memcmp(Str, "iboutlet", 8)) return AT_IBOutlet;
+    if (!memcmp(Str, "sentinel", 8)) return AT_sentinel;
     break;
   case 9:
     if (!memcmp(Str, "dllimport", 9)) return AT_dllimport;

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

==============================================================================
--- cfe/trunk/lib/Sema/SemaDeclAttr.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDeclAttr.cpp Sun Oct  5 13:05:59 2008
@@ -586,6 +586,71 @@
   d->addAttr(new BlocksAttr(type));
 }
 
+static void HandleSentinelAttr(Decl *d, const AttributeList &Attr, Sema &S) {
+  // check the attribute arguments.
+  if (Attr.getNumArgs() > 2) {
+    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments, "0, 1 or 2");
+    return;
+  } 
+  
+  int sentinel = 0;
+  if (Attr.getNumArgs() > 0) {
+    Expr *E = static_cast<Expr *>(Attr.getArg(0));
+    llvm::APSInt Idx(32);
+    if (!E->isIntegerConstantExpr(Idx, S.Context)) {
+      S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int,
+             "sentinel", "1", E->getSourceRange());
+      return;
+    }
+    sentinel = Idx.getZExtValue();
+    
+    if (sentinel < 0) {
+      S.Diag(Attr.getLoc(), diag::err_attribute_sentinel_less_than_zero,
+             E->getSourceRange());
+      return;
+    }
+  }
+
+  int nullPos = 0;
+  if (Attr.getNumArgs() > 1) {
+    Expr *E = static_cast<Expr *>(Attr.getArg(1));
+    llvm::APSInt Idx(32);
+    if (!E->isIntegerConstantExpr(Idx, S.Context)) {
+      S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_int,
+             "sentinel", "2", E->getSourceRange());
+      return;
+    }
+    nullPos = Idx.getZExtValue();
+    
+    if (nullPos > 1 || nullPos < 0) {
+      // FIXME: This error message could be improved, it would be nice
+      // to say what the bounds actually are.
+      S.Diag(Attr.getLoc(), diag::err_attribute_sentinel_not_zero_or_one, 
+             E->getSourceRange());
+      return;
+    }
+  }
+
+  if (FunctionDecl *FD = dyn_cast<FunctionDecl>(d)) {
+    QualType FT = FD->getType();
+    if (!FT->getAsFunctionTypeProto()->isVariadic()) {
+      S.Diag(Attr.getLoc(), diag::warn_attribute_sentinel_not_variadic);
+      return;
+    }    
+  } else if (ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(d)) {
+    if (!MD->isVariadic()) {
+      S.Diag(Attr.getLoc(), diag::warn_attribute_sentinel_not_variadic);
+      return;
+    }    
+  } else {
+    S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type,
+           "sentinel", "function or method");
+    return;
+  }
+  
+  // FIXME: Actually create the attribute.
+}
+
 static void HandleWeakAttr(Decl *d, const AttributeList &Attr, Sema &S) {
   // check the attribute arguments.
   if (Attr.getNumArgs() != 0) {
@@ -1052,6 +1117,7 @@
     break;
   case AttributeList::AT_objc_gc:     HandleObjCGCAttr    (D, Attr, S); break;
   case AttributeList::AT_blocks:      HandleBlocksAttr    (D, Attr, S); break;
+  case AttributeList::AT_sentinel:    HandleSentinelAttr  (D, Attr, S); break;
   default:
 #if 0
     // TODO: when we have the full set of attributes, warn about unknown ones.

Added: cfe/trunk/test/Sema/sentinel-attribute.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/sentinel-attribute.c?rev=57121&view=auto

==============================================================================
--- cfe/trunk/test/Sema/sentinel-attribute.c (added)
+++ cfe/trunk/test/Sema/sentinel-attribute.c Sun Oct  5 13:05:59 2008
@@ -0,0 +1,13 @@
+// RUN: clang -fsyntax-only -verify %s
+int x __attribute__((sentinel)); //expected-warning{{'sentinel' attribute only applies to function or method types}}
+
+void f1(int a, ...) __attribute__ ((sentinel));
+void f2(int a, ...) __attribute__ ((sentinel(1)));
+
+void f3(int a, ...) __attribute__ ((sentinel("hello"))); //expected-error{{'sentinel' attribute requires parameter 1 to be an integer constant}}
+void f4(int a, ...) __attribute__ ((sentinel(1, 2, 3))); //expected-error{{attribute requires 0, 1 or 2 argument(s)}}
+void f4(int a, ...) __attribute__ ((sentinel(-1))); //expected-error{{parameter 1 less than zero}}
+void f4(int a, ...) __attribute__ ((sentinel(0, 2))); // expected-error{{parameter 2 not 0 or 1}}
+
+void f5(int a) __attribute__ ((sentinel)); //expected-warning{{'sentinel' attribute only supported for variadic functions}}
+





More information about the cfe-commits mailing list