1 //===------ SemaMSP430.cpp ----- MSP430 target-specific routines ----------===//
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
7 //===----------------------------------------------------------------------===//
9 // This file implements semantic analysis functions specific to NVPTX.
11 //===----------------------------------------------------------------------===//
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"
23 SemaMSP430::SemaMSP430(Sema
&S
) : SemaBase(S
) {}
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
;
34 if (hasFunctionProto(D
) && getFunctionOrMethodNumParams(D
) != 0) {
35 Diag(D
->getLocation(), diag::warn_interrupt_attribute_invalid
)
40 if (!getFunctionOrMethodResultType(D
)->isVoidType()) {
41 Diag(D
->getLocation(), diag::warn_interrupt_attribute_invalid
)
46 // The attribute takes one integer argument.
47 if (!AL
.checkExactlyNumArgs(SemaRef
, 1))
50 if (!AL
.isArgExpr(0)) {
51 Diag(AL
.getLoc(), diag::err_attribute_argument_type
)
52 << AL
<< AANT_ArgumentIntegerConstant
;
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();
64 // The argument should be in range 0..63.
65 unsigned Num
= NumParams
->getLimitedValue(255);
67 Diag(AL
.getLoc(), diag::err_attribute_argument_out_of_bounds
)
68 << AL
<< (int)NumParams
->getSExtValue()
69 << NumParamsExpr
->getSourceRange();
73 D
->addAttr(::new (getASTContext())
74 MSP430InterruptAttr(getASTContext(), AL
, Num
));
75 D
->addAttr(UsedAttr::CreateImplicit(getASTContext()));