1 //===------ SemaAVR.cpp ---------- AVR 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 AVR. 10 // 11 //===----------------------------------------------------------------------===// 12 13 #include "clang/Sema/SemaAVR.h" 14 #include "clang/AST/DeclBase.h" 15 #include "clang/Basic/DiagnosticSema.h" 16 #include "clang/Sema/Attr.h" 17 #include "clang/Sema/ParsedAttr.h" 18 #include "clang/Sema/Sema.h" 19 20 namespace clang { 21 SemaAVR::SemaAVR(Sema &S) : SemaBase(S) {} 22 23 void SemaAVR::handleInterruptAttr(Decl *D, const ParsedAttr &AL) { 24 if (!isFuncOrMethodForAttrSubject(D)) { 25 Diag(D->getLocation(), diag::warn_attribute_wrong_decl_type) 26 << AL << AL.isRegularKeywordAttribute() << ExpectedFunction; 27 return; 28 } 29 30 if (!AL.checkExactlyNumArgs(SemaRef, 0)) 31 return; 32 33 // AVR interrupt handlers must have no parameter and be void type. 34 if (hasFunctionProto(D) && getFunctionOrMethodNumParams(D) != 0) { 35 Diag(D->getLocation(), diag::warn_interrupt_signal_attribute_invalid) 36 << /*AVR*/ 3 << /*interrupt*/ 0 << 0; 37 return; 38 } 39 if (!getFunctionOrMethodResultType(D)->isVoidType()) { 40 Diag(D->getLocation(), diag::warn_interrupt_signal_attribute_invalid) 41 << /*AVR*/ 3 << /*interrupt*/ 0 << 1; 42 return; 43 } 44 45 handleSimpleAttribute<AVRInterruptAttr>(*this, D, AL); 46 } 47 48 void SemaAVR::handleSignalAttr(Decl *D, const ParsedAttr &AL) { 49 if (!isFuncOrMethodForAttrSubject(D)) { 50 Diag(D->getLocation(), diag::warn_attribute_wrong_decl_type) 51 << AL << AL.isRegularKeywordAttribute() << ExpectedFunction; 52 return; 53 } 54 55 if (!AL.checkExactlyNumArgs(SemaRef, 0)) 56 return; 57 58 // AVR signal handlers must have no parameter and be void type. 59 if (hasFunctionProto(D) && getFunctionOrMethodNumParams(D) != 0) { 60 Diag(D->getLocation(), diag::warn_interrupt_signal_attribute_invalid) 61 << /*AVR*/ 3 << /*signal*/ 1 << 0; 62 return; 63 } 64 if (!getFunctionOrMethodResultType(D)->isVoidType()) { 65 Diag(D->getLocation(), diag::warn_interrupt_signal_attribute_invalid) 66 << /*AVR*/ 3 << /*signal*/ 1 << 1; 67 return; 68 } 69 70 handleSimpleAttribute<AVRSignalAttr>(*this, D, AL); 71 } 72 73 } // namespace clang 74