]> granicus.if.org Git - clang/commitdiff
Implements Sema part of init_priority(priority) attribute
authorFariborz Jahanian <fjahanian@apple.com>
Fri, 18 Jun 2010 21:44:06 +0000 (21:44 +0000)
committerFariborz Jahanian <fjahanian@apple.com>
Fri, 18 Jun 2010 21:44:06 +0000 (21:44 +0000)
(radar 8076356) - wip.

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

include/clang/AST/Attr.h
include/clang/Basic/Attr.td
include/clang/Basic/DiagnosticSemaKinds.td
include/clang/Parse/AttributeList.h
lib/AST/AttrImpl.cpp
lib/Parse/AttributeList.cpp
lib/Sema/SemaDeclAttr.cpp

index 531c74c700b2b67b4f885c9e4de01ef509a14b86..b67b53b10e75b7de9dcaf766125d172b26f8ad33 100644 (file)
@@ -515,6 +515,23 @@ public:
   static bool classof(const ReqdWorkGroupSizeAttr *A) { return true; }
 };
 
+class InitPriorityAttr : public Attr {
+  unsigned Priority;
+public:
+  InitPriorityAttr(unsigned priority) 
+    : Attr(attr::InitPriority),  Priority(priority) {}
+    
+  virtual void Destroy(ASTContext &C) { Attr::Destroy(C); }
+    
+  unsigned getPriority() const { return Priority; }
+    
+  virtual Attr *clone(ASTContext &C) const;
+    
+  static bool classof(const Attr *A) 
+    { return A->getKind() == attr::InitPriority; }
+  static bool classof(const InitPriorityAttr *A) { return true; }
+};
+  
 // Checker-specific attributes.
 DEF_SIMPLE_ATTR(CFReturnsNotRetained);
 DEF_SIMPLE_ATTR(CFReturnsRetained);
index c4f02a0c1b6f18042ff98110df54d331772919e6..4b85bb20db2e79c99903a5e07bc9ead2f9699e19 100644 (file)
@@ -311,6 +311,11 @@ def ReqdWorkGroupSize : Attr {
               UnsignedIntArgument<"ZDim">];
 }
 
+def InitPriority : Attr {
+  let Spellings = ["init_priority"];
+  let Args = [UnsignedIntArgument<"Priority">];
+}
+
 def Section : Attr {
   let Spellings = ["section"];
   let Args = [StringArgument<"Name">];
index 8f9a8f99742e545311cb851494b7884c2e91c1aa..f736ab55fdd01d915fa7f9735c01091d9113a765 100644 (file)
@@ -815,6 +815,9 @@ def err_attribute_missing_parameter_name : Error<
 def err_attribute_invalid_vector_type : Error<"invalid vector type %0">;
 def err_attribute_argument_not_int : Error<
   "'%0' attribute requires integer constant">;
+def err_attribute_argument_outof_range : Error<
+  "init_priority attribute requires integer constant between "
+  "101 and 65535 inclusive">;
 def err_attribute_argument_n_not_int : Error<
   "'%0' attribute requires parameter %1 to be an integer constant">;
 def err_attribute_argument_n_not_string : Error<
index 1e6d3ab9760db7fac60d9d18f3bdbccc6bd840e5..b60a94025e0922a2028dd8811b25cf06145f2c04 100644 (file)
@@ -115,6 +115,7 @@ public:
     AT_weakref,
     AT_weak_import,
     AT_reqd_wg_size,
+    AT_init_priority,
     IgnoredAttribute,
     UnknownAttribute
   };
index 1927a222e8633dd11cd6c0de7a775eab95a9265d..6db43c956522b1731edbfad8a1a736d9fe505332 100644 (file)
@@ -200,6 +200,10 @@ Attr *ReqdWorkGroupSizeAttr::clone(ASTContext &C) const {
   return ::new (C) ReqdWorkGroupSizeAttr(X, Y, Z);
 }
 
+Attr *InitPriorityAttr::clone(ASTContext &C) const {
+  return ::new (C) InitPriorityAttr(Priority);
+}
+
 Attr *MSP430InterruptAttr::clone(ASTContext &C) const {
   return ::new (C) MSP430InterruptAttr(Number);
 }
index 1ebff22e440355022160724cbf2c7bda0447d052..98d5d07e151e0d0cee7f80e14fde338b1af155a6 100644 (file)
@@ -119,6 +119,7 @@ AttributeList::Kind AttributeList::getKind(const IdentifierInfo *Name) {
     .Case("cf_returns_not_retained", AT_cf_returns_not_retained)
     .Case("cf_returns_retained", AT_cf_returns_retained)
     .Case("reqd_work_group_size", AT_reqd_wg_size)
+    .Case("init_priority", AT_init_priority)
     .Case("no_instrument_function", AT_no_instrument_function)
     .Case("thiscall", AT_thiscall)
     .Case("__cdecl", AT_cdecl)
index 89848afe3e1e1004f3e092cf9a753213cbece59f..b54bc1ed9f52dba6120e2a570905623fe5eeefd4 100644 (file)
@@ -1180,6 +1180,39 @@ static FormatAttrKind getFormatAttrKind(llvm::StringRef Format) {
   return InvalidFormat;
 }
 
+/// Handle __attribute__((init_priority(priority))) attributes based on
+/// http://gcc.gnu.org/onlinedocs/gcc/C_002b_002b-Attributes.html
+static void HandleInitPriorityAttr(Decl *d, const AttributeList &Attr, 
+                                   Sema &S) {
+  if (!S.getLangOptions().CPlusPlus) {
+    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << Attr.getName();
+    return;
+  }
+  
+  if (Attr.getNumArgs() != 1) {
+    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
+    Attr.setInvalid();
+    return;
+  }
+  Expr *priorityExpr = static_cast<Expr *>(Attr.getArg(0));
+  llvm::APSInt priority(32);
+  if (priorityExpr->isTypeDependent() || priorityExpr->isValueDependent() ||
+      !priorityExpr->isIntegerConstantExpr(priority, S.Context)) {
+    S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_int)
+    << "init_priority" << priorityExpr->getSourceRange();
+    Attr.setInvalid();
+    return;
+  }
+  unsigned prioritynum = static_cast<unsigned>(priority.getZExtValue() * 8);
+  if (prioritynum < 101 || prioritynum > 65535) {
+    S.Diag(Attr.getLoc(), diag::err_attribute_argument_outof_range)
+    <<  priorityExpr->getSourceRange();
+    Attr.setInvalid();
+    return;
+  }
+  d->addAttr(::new (S.Context) InitPriorityAttr(prioritynum));
+}
+
 /// Handle __attribute__((format(type,idx,firstarg))) attributes based on
 /// http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html
 static void HandleFormatAttr(Decl *d, const AttributeList &Attr, Sema &S) {
@@ -1951,6 +1984,9 @@ static void ProcessDeclAttribute(Scope *scope, Decl *D,
   case AttributeList::AT_reqd_wg_size:
     HandleReqdWorkGroupSize(D, Attr, S); break;
 
+  case AttributeList::AT_init_priority: 
+      HandleInitPriorityAttr(D, Attr, S); break;
+      
   case AttributeList::AT_packed:      HandlePackedAttr      (D, Attr, S); break;
   case AttributeList::AT_section:     HandleSectionAttr     (D, Attr, S); break;
   case AttributeList::AT_unavailable: HandleUnavailableAttr (D, Attr, S); break;