Implements Sema part of init_priority(priority) attribute

(radar 8076356) - wip.

llvm-svn: 106322
This commit is contained in:
Fariborz Jahanian 2010-06-18 21:44:06 +00:00
parent d64dfc1568
commit ef5f621215
7 changed files with 67 additions and 0 deletions

View 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);

View 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">];

View 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<

View File

@ -115,6 +115,7 @@ public:
AT_weakref,
AT_weak_import,
AT_reqd_wg_size,
AT_init_priority,
IgnoredAttribute,
UnknownAttribute
};

View 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);
}

View 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)

View 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;