Example #1
0
static void HandleMSP430InterruptAttr(Decl *d,
                                      const AttributeList &Attr, Sema &S) {
  if (Attr.getNumArgs() != 1) {
    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments)
      << Attr.getName() << 1;
    return;
  }

  if (!Attr.isArgExpr(0)) {
    S.Diag(Attr.getLoc(), diag::err_attribute_argument_type) << Attr.getName()
      << AANT_ArgumentIntegerConstant;
    return;
  }

  // FIXME: Check for decl - it should be void ()(void).
  Expr *NumParamsExpr = Attr.getArgAsExpr(0);
  llvm::APSInt NumParams(32);
  if (!NumParamsExpr->isIntegerConstantExpr(NumParams, S.Context)) {
    S.Diag(Attr.getLoc(), diag::err_attribute_argument_type)
      << Attr.getName() << AANT_ArgumentIntegerConstant
      << 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));
}