aboutsummaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorFariborz Jahanian <fjahanian@apple.com>2010-06-18 21:44:06 +0000
committerFariborz Jahanian <fjahanian@apple.com>2010-06-18 21:44:06 +0000
commit521f12d3dfdbb0e93d1bcb503d074e67acdc489c (patch)
treedbf9c597eb8e4d5ead31fd162f5296ed356e0bb0 /lib
parent8e19890c329279c5ac35ab71a35423d429d80165 (diff)
Implements Sema part of init_priority(priority) attribute
(radar 8076356) - wip. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@106322 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib')
-rw-r--r--lib/AST/AttrImpl.cpp4
-rw-r--r--lib/Parse/AttributeList.cpp1
-rw-r--r--lib/Sema/SemaDeclAttr.cpp36
3 files changed, 41 insertions, 0 deletions
diff --git a/lib/AST/AttrImpl.cpp b/lib/AST/AttrImpl.cpp
index 1927a222e8..6db43c9565 100644
--- a/lib/AST/AttrImpl.cpp
+++ b/lib/AST/AttrImpl.cpp
@@ -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);
}
diff --git a/lib/Parse/AttributeList.cpp b/lib/Parse/AttributeList.cpp
index 1ebff22e44..98d5d07e15 100644
--- a/lib/Parse/AttributeList.cpp
+++ b/lib/Parse/AttributeList.cpp
@@ -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)
diff --git a/lib/Sema/SemaDeclAttr.cpp b/lib/Sema/SemaDeclAttr.cpp
index 89848afe3e..b54bc1ed9f 100644
--- a/lib/Sema/SemaDeclAttr.cpp
+++ b/lib/Sema/SemaDeclAttr.cpp
@@ -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;