diff options
| author | Dylan McKay <me@dylanmckay.io> | 2017-02-08 05:09:26 +0000 |
|---|---|---|
| committer | Dylan McKay <me@dylanmckay.io> | 2017-02-08 05:09:26 +0000 |
| commit | e8232d73f534492d84cb8baee90eeaa63545ddd2 (patch) | |
| tree | c2d51e6423d5784e16b7aa390edffe6351d4b582 /clang/lib | |
| parent | a6ae060db4fdf6da2c27bb80f3281a0ce96558f8 (diff) | |
| download | bcm5719-llvm-e8232d73f534492d84cb8baee90eeaa63545ddd2.tar.gz bcm5719-llvm-e8232d73f534492d84cb8baee90eeaa63545ddd2.zip | |
[AVR] Add support for the 'interrupt' and 'naked' attributes
Summary:
This teaches clang how to parse and lower the 'interrupt' and 'naked'
attributes.
This allows interrupt signal handlers to be written.
Reviewers: aaron.ballman
Subscribers: malcolm.parsons, cfe-commits
Differential Revision: https://reviews.llvm.org/D28451
llvm-svn: 294402
Diffstat (limited to 'clang/lib')
| -rw-r--r-- | clang/lib/CodeGen/TargetInfo.cpp | 28 | ||||
| -rw-r--r-- | clang/lib/Sema/SemaDeclAttr.cpp | 32 |
2 files changed, 60 insertions, 0 deletions
diff --git a/clang/lib/CodeGen/TargetInfo.cpp b/clang/lib/CodeGen/TargetInfo.cpp index f0a27f9d560..19b63ce6213 100644 --- a/clang/lib/CodeGen/TargetInfo.cpp +++ b/clang/lib/CodeGen/TargetInfo.cpp @@ -6900,6 +6900,31 @@ MIPSTargetCodeGenInfo::initDwarfEHRegSizeTable(CodeGen::CodeGenFunction &CGF, } //===----------------------------------------------------------------------===// +// AVR ABI Implementation. +//===----------------------------------------------------------------------===// + +namespace { +class AVRTargetCodeGenInfo : public TargetCodeGenInfo { +public: + AVRTargetCodeGenInfo(CodeGenTypes &CGT) + : TargetCodeGenInfo(new DefaultABIInfo(CGT)) { } + + void setTargetAttributes(const Decl *D, llvm::GlobalValue *GV, + CodeGen::CodeGenModule &CGM) const override { + const auto *FD = dyn_cast_or_null<FunctionDecl>(D); + if (!FD) return; + auto *Fn = cast<llvm::Function>(GV); + + if (FD->getAttr<AVRInterruptAttr>()) + Fn->addFnAttr("interrupt"); + + if (FD->getAttr<AVRSignalAttr>()) + Fn->addFnAttr("signal"); + } +}; +} + +//===----------------------------------------------------------------------===// // TCE ABI Implementation (see http://tce.cs.tut.fi). Uses mostly the defaults. // Currently subclassed only to implement custom OpenCL C function attribute // handling. @@ -8402,6 +8427,9 @@ const TargetCodeGenInfo &CodeGenModule::getTargetCodeGenInfo() { case llvm::Triple::mips64el: return SetCGInfo(new MIPSTargetCodeGenInfo(Types, false)); + case llvm::Triple::avr: + return SetCGInfo(new AVRTargetCodeGenInfo(Types)); + case llvm::Triple::aarch64: case llvm::Triple::aarch64_be: { AArch64ABIInfo::ABIKind Kind = AArch64ABIInfo::AAPCS; diff --git a/clang/lib/Sema/SemaDeclAttr.cpp b/clang/lib/Sema/SemaDeclAttr.cpp index c6a5bc74145..7d3793e2fd6 100644 --- a/clang/lib/Sema/SemaDeclAttr.cpp +++ b/clang/lib/Sema/SemaDeclAttr.cpp @@ -5126,6 +5126,32 @@ static void handleAnyX86InterruptAttr(Sema &S, Decl *D, D->addAttr(UsedAttr::CreateImplicit(S.Context)); } +static void handleAVRInterruptAttr(Sema &S, Decl *D, const AttributeList &Attr) { + if (!isFunctionOrMethod(D)) { + S.Diag(D->getLocation(), diag::warn_attribute_wrong_decl_type) + << "'interrupt'" << ExpectedFunction; + return; + } + + if (!checkAttributeNumArgs(S, Attr, 0)) + return; + + handleSimpleAttribute<AVRInterruptAttr>(S, D, Attr); +} + +static void handleAVRSignalAttr(Sema &S, Decl *D, const AttributeList &Attr) { + if (!isFunctionOrMethod(D)) { + S.Diag(D->getLocation(), diag::warn_attribute_wrong_decl_type) + << "'signal'" << ExpectedFunction; + return; + } + + if (!checkAttributeNumArgs(S, Attr, 0)) + return; + + handleSimpleAttribute<AVRSignalAttr>(S, D, Attr); +} + static void handleInterruptAttr(Sema &S, Decl *D, const AttributeList &Attr) { // Dispatch the interrupt attribute based on the current target. switch (S.Context.getTargetInfo().getTriple().getArch()) { @@ -5140,6 +5166,9 @@ static void handleInterruptAttr(Sema &S, Decl *D, const AttributeList &Attr) { case llvm::Triple::x86_64: handleAnyX86InterruptAttr(S, D, Attr); break; + case llvm::Triple::avr: + handleAVRInterruptAttr(S, D, Attr); + break; default: handleARMInterruptAttr(S, D, Attr); break; @@ -5700,6 +5729,9 @@ static void ProcessDeclAttribute(Sema &S, Scope *scope, Decl *D, case AttributeList::AT_AMDGPUNumVGPR: handleAMDGPUNumVGPRAttr(S, D, Attr); break; + case AttributeList::AT_AVRSignal: + handleAVRSignalAttr(S, D, Attr); + break; case AttributeList::AT_IBAction: handleSimpleAttribute<IBActionAttr>(S, D, Attr); break; |

