1 //===------ SemaMSP430.cpp ----- MSP430 target-specific routines ----------===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 // 9 // This file implements semantic analysis functions specific to NVPTX. 10 // 11 //===----------------------------------------------------------------------===// 12 13 #include "clang/Sema/SemaMSP430.h" 14 #include "clang/AST/ASTContext.h" 15 #include "clang/AST/Attr.h" 16 #include "clang/AST/DeclBase.h" 17 #include "clang/Basic/DiagnosticSema.h" 18 #include "clang/Sema/Attr.h" 19 #include "clang/Sema/ParsedAttr.h" 20 21 namespace clang { 22 23 SemaMSP430::SemaMSP430(Sema &S) : SemaBase(S) {} 24 25 void SemaMSP430::handleInterruptAttr(Decl *D, const ParsedAttr &AL) { 26 // MSP430 'interrupt' attribute is applied to 27 // a function with no parameters and void return type. 28 if (!isFuncOrMethodForAttrSubject(D)) { 29 Diag(D->getLocation(), diag::warn_attribute_wrong_decl_type) 30 << AL << AL.isRegularKeywordAttribute() << ExpectedFunctionOrMethod; 31 return; 32 } 33 34 if (hasFunctionProto(D) && getFunctionOrMethodNumParams(D) != 0) { 35 Diag(D->getLocation(), diag::warn_interrupt_attribute_invalid) 36 << /*MSP430*/ 1 << 0; 37 return; 38 } 39 40 if (!getFunctionOrMethodResultType(D)->isVoidType()) { 41 Diag(D->getLocation(), diag::warn_interrupt_attribute_invalid) 42 << /*MSP430*/ 1 << 1; 43 return; 44 } 45 46 // The attribute takes one integer argument. 47 if (!AL.checkExactlyNumArgs(SemaRef, 1)) 48 return; 49 50 if (!AL.isArgExpr(0)) { 51 Diag(AL.getLoc(), diag::err_attribute_argument_type) 52 << AL << AANT_ArgumentIntegerConstant; 53 return; 54 } 55 56 Expr *NumParamsExpr = static_cast<Expr *>(AL.getArgAsExpr(0)); 57 std::optional<llvm::APSInt> NumParams = llvm::APSInt(32); 58 if (!(NumParams = NumParamsExpr->getIntegerConstantExpr(getASTContext()))) { 59 Diag(AL.getLoc(), diag::err_attribute_argument_type) 60 << AL << AANT_ArgumentIntegerConstant 61 << NumParamsExpr->getSourceRange(); 62 return; 63 } 64 // The argument should be in range 0..63. 65 unsigned Num = NumParams->getLimitedValue(255); 66 if (Num > 63) { 67 Diag(AL.getLoc(), diag::err_attribute_argument_out_of_bounds) 68 << AL << (int)NumParams->getSExtValue() 69 << NumParamsExpr->getSourceRange(); 70 return; 71 } 72 73 D->addAttr(::new (getASTContext()) 74 MSP430InterruptAttr(getASTContext(), AL, Num)); 75 D->addAttr(UsedAttr::CreateImplicit(getASTContext())); 76 } 77 78 } // namespace clang 79