static void HandleMSP430InterruptAttr(Decl *d, const AttributeList &Attr, Sema &S) { // Check the attribute arguments. if (Attr.getNumArgs() != 1) { S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; return; } // FIXME: Check for decl - it should be void ()(void). Expr *NumParamsExpr = static_cast<Expr *>(Attr.getArg(0)); llvm::APSInt NumParams(32); if (!NumParamsExpr->isIntegerConstantExpr(NumParams, S.Context)) { S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_int) << "interrupt" << NumParamsExpr->getSourceRange(); return; } unsigned Num = NumParams.getLimitedValue(255); if ((Num & 1) || Num > 30) { S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_bounds) << "interrupt" << (int)NumParams.getSExtValue() << NumParamsExpr->getSourceRange(); return; } d->addAttr(::new (S.Context) MSP430InterruptAttr(Attr.getLoc(), S.Context, Num)); d->addAttr(::new (S.Context) UsedAttr(Attr.getLoc(), S.Context)); }
/// HandleAddressSpaceTypeAttribute - Process an address_space attribute on the /// specified type. The attribute contains 1 argument, the id of the address /// space for the type. static void HandleAddressSpaceTypeAttribute(QualType &Type, const AttributeList &Attr, Sema &S){ // If this type is already address space qualified, reject it. // Clause 6.7.3 - Type qualifiers: "No type shall be qualified by qualifiers // for two or more different address spaces." if (Type.getAddressSpace()) { S.Diag(Attr.getLoc(), diag::err_attribute_address_multiple_qualifiers); return; } // Check the attribute arguments. if (Attr.getNumArgs() != 1) { S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; return; } Expr *ASArgExpr = static_cast<Expr *>(Attr.getArg(0)); llvm::APSInt addrSpace(32); if (!ASArgExpr->isIntegerConstantExpr(addrSpace, S.Context)) { S.Diag(Attr.getLoc(), diag::err_attribute_address_space_not_int) << ASArgExpr->getSourceRange(); return; } unsigned ASIdx = static_cast<unsigned>(addrSpace.getZExtValue()); Type = S.Context.getAddrSpaceQualType(Type, ASIdx); }