1*0fca6ea1SDimitry Andric //===------ SemaMSP430.cpp ----- MSP430 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 NVPTX. 10*0fca6ea1SDimitry Andric // 11*0fca6ea1SDimitry Andric //===----------------------------------------------------------------------===// 12*0fca6ea1SDimitry Andric 13*0fca6ea1SDimitry Andric #include "clang/Sema/SemaMSP430.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/Attr.h" 19*0fca6ea1SDimitry Andric #include "clang/Sema/ParsedAttr.h" 20*0fca6ea1SDimitry Andric 21*0fca6ea1SDimitry Andric namespace clang { 22*0fca6ea1SDimitry Andric 23*0fca6ea1SDimitry Andric SemaMSP430::SemaMSP430(Sema &S) : SemaBase(S) {} 24*0fca6ea1SDimitry Andric 25*0fca6ea1SDimitry Andric void SemaMSP430::handleInterruptAttr(Decl *D, const ParsedAttr &AL) { 26*0fca6ea1SDimitry Andric // MSP430 'interrupt' attribute is applied to 27*0fca6ea1SDimitry Andric // a function with no parameters and void return type. 28*0fca6ea1SDimitry Andric if (!isFuncOrMethodForAttrSubject(D)) { 29*0fca6ea1SDimitry Andric Diag(D->getLocation(), diag::warn_attribute_wrong_decl_type) 30*0fca6ea1SDimitry Andric << AL << AL.isRegularKeywordAttribute() << ExpectedFunctionOrMethod; 31*0fca6ea1SDimitry Andric return; 32*0fca6ea1SDimitry Andric } 33*0fca6ea1SDimitry Andric 34*0fca6ea1SDimitry Andric if (hasFunctionProto(D) && getFunctionOrMethodNumParams(D) != 0) { 35*0fca6ea1SDimitry Andric Diag(D->getLocation(), diag::warn_interrupt_attribute_invalid) 36*0fca6ea1SDimitry Andric << /*MSP430*/ 1 << 0; 37*0fca6ea1SDimitry Andric return; 38*0fca6ea1SDimitry Andric } 39*0fca6ea1SDimitry Andric 40*0fca6ea1SDimitry Andric if (!getFunctionOrMethodResultType(D)->isVoidType()) { 41*0fca6ea1SDimitry Andric Diag(D->getLocation(), diag::warn_interrupt_attribute_invalid) 42*0fca6ea1SDimitry Andric << /*MSP430*/ 1 << 1; 43*0fca6ea1SDimitry Andric return; 44*0fca6ea1SDimitry Andric } 45*0fca6ea1SDimitry Andric 46*0fca6ea1SDimitry Andric // The attribute takes one integer argument. 47*0fca6ea1SDimitry Andric if (!AL.checkExactlyNumArgs(SemaRef, 1)) 48*0fca6ea1SDimitry Andric return; 49*0fca6ea1SDimitry Andric 50*0fca6ea1SDimitry Andric if (!AL.isArgExpr(0)) { 51*0fca6ea1SDimitry Andric Diag(AL.getLoc(), diag::err_attribute_argument_type) 52*0fca6ea1SDimitry Andric << AL << AANT_ArgumentIntegerConstant; 53*0fca6ea1SDimitry Andric return; 54*0fca6ea1SDimitry Andric } 55*0fca6ea1SDimitry Andric 56*0fca6ea1SDimitry Andric Expr *NumParamsExpr = static_cast<Expr *>(AL.getArgAsExpr(0)); 57*0fca6ea1SDimitry Andric std::optional<llvm::APSInt> NumParams = llvm::APSInt(32); 58*0fca6ea1SDimitry Andric if (!(NumParams = NumParamsExpr->getIntegerConstantExpr(getASTContext()))) { 59*0fca6ea1SDimitry Andric Diag(AL.getLoc(), diag::err_attribute_argument_type) 60*0fca6ea1SDimitry Andric << AL << AANT_ArgumentIntegerConstant 61*0fca6ea1SDimitry Andric << NumParamsExpr->getSourceRange(); 62*0fca6ea1SDimitry Andric return; 63*0fca6ea1SDimitry Andric } 64*0fca6ea1SDimitry Andric // The argument should be in range 0..63. 65*0fca6ea1SDimitry Andric unsigned Num = NumParams->getLimitedValue(255); 66*0fca6ea1SDimitry Andric if (Num > 63) { 67*0fca6ea1SDimitry Andric Diag(AL.getLoc(), diag::err_attribute_argument_out_of_bounds) 68*0fca6ea1SDimitry Andric << AL << (int)NumParams->getSExtValue() 69*0fca6ea1SDimitry Andric << NumParamsExpr->getSourceRange(); 70*0fca6ea1SDimitry Andric return; 71*0fca6ea1SDimitry Andric } 72*0fca6ea1SDimitry Andric 73*0fca6ea1SDimitry Andric D->addAttr(::new (getASTContext()) 74*0fca6ea1SDimitry Andric MSP430InterruptAttr(getASTContext(), AL, Num)); 75*0fca6ea1SDimitry Andric D->addAttr(UsedAttr::CreateImplicit(getASTContext())); 76*0fca6ea1SDimitry Andric } 77*0fca6ea1SDimitry Andric 78*0fca6ea1SDimitry Andric } // namespace clang 79