1*0fca6ea1SDimitry Andric //===------ SemaM68k.cpp -------- M68k target-specific routines -----------===// 2*0fca6ea1SDimitry Andric // 3*0fca6ea1SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4*0fca6ea1SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 5*0fca6ea1SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6*0fca6ea1SDimitry Andric // 7*0fca6ea1SDimitry Andric //===----------------------------------------------------------------------===// 8*0fca6ea1SDimitry Andric // 9*0fca6ea1SDimitry Andric // This file implements semantic analysis functions specific to M68k. 10*0fca6ea1SDimitry Andric // 11*0fca6ea1SDimitry Andric //===----------------------------------------------------------------------===// 12*0fca6ea1SDimitry Andric 13*0fca6ea1SDimitry Andric #include "clang/Sema/SemaM68k.h" 14*0fca6ea1SDimitry Andric #include "clang/AST/ASTContext.h" 15*0fca6ea1SDimitry Andric #include "clang/AST/Attr.h" 16*0fca6ea1SDimitry Andric #include "clang/AST/DeclBase.h" 17*0fca6ea1SDimitry Andric #include "clang/Basic/DiagnosticSema.h" 18*0fca6ea1SDimitry Andric #include "clang/Sema/ParsedAttr.h" 19*0fca6ea1SDimitry Andric 20*0fca6ea1SDimitry Andric namespace clang { SemaM68k(Sema & S)21*0fca6ea1SDimitry AndricSemaM68k::SemaM68k(Sema &S) : SemaBase(S) {} 22*0fca6ea1SDimitry Andric handleInterruptAttr(Decl * D,const ParsedAttr & AL)23*0fca6ea1SDimitry Andricvoid SemaM68k::handleInterruptAttr(Decl *D, const ParsedAttr &AL) { 24*0fca6ea1SDimitry Andric if (!AL.checkExactlyNumArgs(SemaRef, 1)) 25*0fca6ea1SDimitry Andric return; 26*0fca6ea1SDimitry Andric 27*0fca6ea1SDimitry Andric if (!AL.isArgExpr(0)) { 28*0fca6ea1SDimitry Andric Diag(AL.getLoc(), diag::err_attribute_argument_type) 29*0fca6ea1SDimitry Andric << AL << AANT_ArgumentIntegerConstant; 30*0fca6ea1SDimitry Andric return; 31*0fca6ea1SDimitry Andric } 32*0fca6ea1SDimitry Andric 33*0fca6ea1SDimitry Andric // FIXME: Check for decl - it should be void ()(void). 34*0fca6ea1SDimitry Andric 35*0fca6ea1SDimitry Andric Expr *NumParamsExpr = static_cast<Expr *>(AL.getArgAsExpr(0)); 36*0fca6ea1SDimitry Andric auto MaybeNumParams = NumParamsExpr->getIntegerConstantExpr(getASTContext()); 37*0fca6ea1SDimitry Andric if (!MaybeNumParams) { 38*0fca6ea1SDimitry Andric Diag(AL.getLoc(), diag::err_attribute_argument_type) 39*0fca6ea1SDimitry Andric << AL << AANT_ArgumentIntegerConstant 40*0fca6ea1SDimitry Andric << NumParamsExpr->getSourceRange(); 41*0fca6ea1SDimitry Andric return; 42*0fca6ea1SDimitry Andric } 43*0fca6ea1SDimitry Andric 44*0fca6ea1SDimitry Andric unsigned Num = MaybeNumParams->getLimitedValue(255); 45*0fca6ea1SDimitry Andric if ((Num & 1) || Num > 30) { 46*0fca6ea1SDimitry Andric Diag(AL.getLoc(), diag::err_attribute_argument_out_of_bounds) 47*0fca6ea1SDimitry Andric << AL << (int)MaybeNumParams->getSExtValue() 48*0fca6ea1SDimitry Andric << NumParamsExpr->getSourceRange(); 49*0fca6ea1SDimitry Andric return; 50*0fca6ea1SDimitry Andric } 51*0fca6ea1SDimitry Andric 52*0fca6ea1SDimitry Andric D->addAttr(::new (getASTContext()) 53*0fca6ea1SDimitry Andric M68kInterruptAttr(getASTContext(), AL, Num)); 54*0fca6ea1SDimitry Andric D->addAttr(UsedAttr::CreateImplicit(getASTContext())); 55*0fca6ea1SDimitry Andric } 56*0fca6ea1SDimitry Andric } // namespace clang 57