[PATCH] D28451: [AVR] Add support for the 'interrupt' and 'naked' attributes
This revision was automatically updated to reflect the committed changes. Closed by commit rL294402: [AVR] Add support for the 'interrupt' and 'naked' attributes (authored by dylanmckay). Changed prior to commit: https://reviews.llvm.org/D28451?vs=87365=87588#toc Repository: rL LLVM https://reviews.llvm.org/D28451 Files: cfe/trunk/include/clang/Basic/Attr.td cfe/trunk/include/clang/Basic/AttrDocs.td cfe/trunk/lib/CodeGen/TargetInfo.cpp cfe/trunk/lib/Sema/SemaDeclAttr.cpp cfe/trunk/test/CodeGen/avr/attributes/interrupt.c cfe/trunk/test/CodeGen/avr/attributes/signal.c cfe/trunk/test/Sema/avr-interrupt-attr.c cfe/trunk/test/Sema/avr-signal-attr.c Index: cfe/trunk/include/clang/Basic/AttrDocs.td === --- cfe/trunk/include/clang/Basic/AttrDocs.td +++ cfe/trunk/include/clang/Basic/AttrDocs.td @@ -1182,6 +1182,33 @@ }]; } +def AVRInterruptDocs : Documentation { + let Category = DocCatFunction; + let Content = [{ +Clang supports the GNU style ``__attribute__((interrupt))`` attribute on +AVR targets. This attribute may be attached to a function definition and instructs +the backend to generate appropriate function entry/exit code so that it can be used +directly as an interrupt service routine. + +On the AVR, the hardware globally disables interrupts when an interrupt is executed. +The first instruction of an interrupt handler declared with this attribute is a SEI +instruction to re-enable interrupts. See also the signal attribute that +does not insert a SEI instruction. + }]; +} + +def AVRSignalDocs : Documentation { + let Category = DocCatFunction; + let Content = [{ +Clang supports the GNU style ``__attribute__((signal))`` attribute on +AVR targets. This attribute may be attached to a function definition and instructs +the backend to generate appropriate function entry/exit code so that it can be used +directly as an interrupt service routine. + +Interrupt handler functions defined with the signal attribute do not re-enable interrupts. +}]; +} + def TargetDocs : Documentation { let Category = DocCatFunction; let Content = [{ Index: cfe/trunk/include/clang/Basic/Attr.td === --- cfe/trunk/include/clang/Basic/Attr.td +++ cfe/trunk/include/clang/Basic/Attr.td @@ -258,6 +258,7 @@ list CXXABIs; } def TargetARM : TargetArch<["arm", "thumb", "armeb", "thumbeb"]>; +def TargetAVR : TargetArch<["avr"]>; def TargetMips : TargetArch<["mips", "mipsel"]>; def TargetMSP430 : TargetArch<["msp430"]>; def TargetX86 : TargetArch<["x86"]>; @@ -480,6 +481,19 @@ let Documentation = [ARMInterruptDocs]; } +def AVRInterrupt : InheritableAttr, TargetSpecificAttr { + let Spellings = [GNU<"interrupt">]; + let Subjects = SubjectList<[Function]>; + let ParseKind = "Interrupt"; + let Documentation = [AVRInterruptDocs]; +} + +def AVRSignal : InheritableAttr, TargetSpecificAttr { + let Spellings = [GNU<"signal">]; + let Subjects = SubjectList<[Function]>; + let Documentation = [AVRSignalDocs]; +} + def AsmLabel : InheritableAttr { let Spellings = [Keyword<"asm">, Keyword<"__asm__">]; let Args = [StringArgument<"Label">]; Index: cfe/trunk/test/CodeGen/avr/attributes/signal.c === --- cfe/trunk/test/CodeGen/avr/attributes/signal.c +++ cfe/trunk/test/CodeGen/avr/attributes/signal.c @@ -0,0 +1,6 @@ +// RUN: %clang_cc1 -triple avr-unknown-unknown -emit-llvm %s -o - | FileCheck %s + +// CHECK: define void @foo() #0 +__attribute__((signal)) void foo(void) { } + +// CHECK: attributes #0 = {{{.*signal.*}}} Index: cfe/trunk/test/CodeGen/avr/attributes/interrupt.c === --- cfe/trunk/test/CodeGen/avr/attributes/interrupt.c +++ cfe/trunk/test/CodeGen/avr/attributes/interrupt.c @@ -0,0 +1,6 @@ +// RUN: %clang_cc1 -triple avr-unknown-unknown -emit-llvm %s -o - | FileCheck %s + +// CHECK: define void @foo() #0 +__attribute__((interrupt)) void foo(void) { } + +// CHECK: attributes #0 = {{{.*interrupt.*}}} Index: cfe/trunk/test/Sema/avr-signal-attr.c === --- cfe/trunk/test/Sema/avr-signal-attr.c +++ cfe/trunk/test/Sema/avr-signal-attr.c @@ -0,0 +1,8 @@ +// RUN: %clang_cc1 %s -triple avr-unknown-unknown -verify -fsyntax-only +struct a { int b; }; + +struct a test __attribute__((signal)); // expected-warning {{'signal' attribute only applies to functions}} + +__attribute__((signal(12))) void foo(void) { } // expected-error {{'signal' attribute takes no arguments}} + +__attribute__((signal)) void food() {} Index: cfe/trunk/test/Sema/avr-interrupt-attr.c === --- cfe/trunk/test/Sema/avr-interrupt-attr.c +++ cfe/trunk/test/Sema/avr-interrupt-attr.c @@ -0,0 +1,8 @@ +// RUN: %clang_cc1 %s -triple avr-unknown-unknown -verify
[PATCH] D28451: [AVR] Add support for the 'interrupt' and 'naked' attributes
aaron.ballman accepted this revision. aaron.ballman added a comment. This revision is now accepted and ready to land. LGTM! https://reviews.llvm.org/D28451 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D28451: [AVR] Add support for the 'interrupt' and 'naked' attributes
dylanmckay updated this revision to Diff 87365. dylanmckay marked 4 inline comments as done. dylanmckay added a comment. Remove 'Attr.setInvalid()' https://reviews.llvm.org/D28451 Files: include/clang/Basic/Attr.td include/clang/Basic/AttrDocs.td lib/CodeGen/TargetInfo.cpp lib/Sema/SemaDeclAttr.cpp test/CodeGen/avr/attributes/interrupt.c test/CodeGen/avr/attributes/signal.c test/Sema/avr-interrupt-attr.c test/Sema/avr-signal-attr.c Index: test/Sema/avr-signal-attr.c === --- /dev/null +++ test/Sema/avr-signal-attr.c @@ -0,0 +1,8 @@ +// RUN: %clang_cc1 %s -triple avr-unknown-unknown -verify -fsyntax-only +struct a { int b; }; + +struct a test __attribute__((signal)); // expected-warning {{'signal' attribute only applies to functions}} + +__attribute__((signal(12))) void foo(void) { } // expected-error {{'signal' attribute takes no arguments}} + +__attribute__((signal)) void food() {} Index: test/Sema/avr-interrupt-attr.c === --- /dev/null +++ test/Sema/avr-interrupt-attr.c @@ -0,0 +1,8 @@ +// RUN: %clang_cc1 %s -triple avr-unknown-unknown -verify -fsyntax-only +struct a { int b; }; + +struct a test __attribute__((interrupt)); // expected-warning {{'interrupt' attribute only applies to functions}} + +__attribute__((interrupt(12))) void foo(void) { } // expected-error {{'interrupt' attribute takes no arguments}} + +__attribute__((interrupt)) void food() {} Index: test/CodeGen/avr/attributes/signal.c === --- /dev/null +++ test/CodeGen/avr/attributes/signal.c @@ -0,0 +1,6 @@ +// RUN: %clang_cc1 -triple avr-unknown-unknown -emit-llvm %s -o - | FileCheck %s + +// CHECK: define void @foo() #0 +__attribute__((signal)) void foo(void) { } + +// CHECK: attributes #0 = {{{.*signal.*}}} Index: test/CodeGen/avr/attributes/interrupt.c === --- /dev/null +++ test/CodeGen/avr/attributes/interrupt.c @@ -0,0 +1,6 @@ +// RUN: %clang_cc1 -triple avr-unknown-unknown -emit-llvm %s -o - | FileCheck %s + +// CHECK: define void @foo() #0 +__attribute__((interrupt)) void foo(void) { } + +// CHECK: attributes #0 = {{{.*interrupt.*}}} Index: lib/Sema/SemaDeclAttr.cpp === --- lib/Sema/SemaDeclAttr.cpp +++ lib/Sema/SemaDeclAttr.cpp @@ -5126,6 +5126,32 @@ D->addAttr(UsedAttr::CreateImplicit(S.Context)); } +static void handleAVRInterruptAttr(Sema , Decl *D, const AttributeList ) { + if (!isFunctionOrMethod(D)) { +S.Diag(D->getLocation(), diag::warn_attribute_wrong_decl_type) +<< "'interrupt'" << ExpectedFunction; +return; + } + + if (!checkAttributeNumArgs(S, Attr, 0)) +return; + + handleSimpleAttribute(S, D, Attr); +} + +static void handleAVRSignalAttr(Sema , Decl *D, const AttributeList ) { + if (!isFunctionOrMethod(D)) { +S.Diag(D->getLocation(), diag::warn_attribute_wrong_decl_type) +<< "'signal'" << ExpectedFunction; +return; + } + + if (!checkAttributeNumArgs(S, Attr, 0)) +return; + + handleSimpleAttribute(S, D, Attr); +} + static void handleInterruptAttr(Sema , Decl *D, const AttributeList ) { // Dispatch the interrupt attribute based on the current target. switch (S.Context.getTargetInfo().getTriple().getArch()) { @@ -5140,6 +5166,9 @@ 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 @@ case AttributeList::AT_AMDGPUNumVGPR: handleAMDGPUNumVGPRAttr(S, D, Attr); break; + case AttributeList::AT_AVRSignal: +handleAVRSignalAttr(S, D, Attr); +break; case AttributeList::AT_IBAction: handleSimpleAttribute(S, D, Attr); break; Index: lib/CodeGen/TargetInfo.cpp === --- lib/CodeGen/TargetInfo.cpp +++ lib/CodeGen/TargetInfo.cpp @@ -6900,6 +6900,31 @@ } //===--===// +// AVR ABI Implementation. +//===--===// + +namespace { +class AVRTargetCodeGenInfo : public TargetCodeGenInfo { +public: + AVRTargetCodeGenInfo(CodeGenTypes ) +: TargetCodeGenInfo(new DefaultABIInfo(CGT)) { } + + void setTargetAttributes(const Decl *D, llvm::GlobalValue *GV, + CodeGen::CodeGenModule ) const override { +const auto *FD = dyn_cast_or_null(D); +if (!FD) return; +auto *Fn = cast(GV); + +if (FD->getAttr()) + Fn->addFnAttr("interrupt"); + +if (FD->getAttr()) + Fn->addFnAttr("signal"); + } +}; +} + +//===--===// // TCE
[PATCH] D28451: [AVR] Add support for the 'interrupt' and 'naked' attributes
dylanmckay added inline comments. Comment at: test/CodeGen/avr/attributes/interrupt.c:3 + +// CHECK: define void @foo() #0 +__attribute__((interrupt)) void foo(void) { } aaron.ballman wrote: > dylanmckay wrote: > > aaron.ballman wrote: > > > As should this. > > It seems like this sort of test _does_ sit in `CodeGen` - see > > `test/CodeGen/{arm-interrupt-attr.c|mips-interrupt-attr.c}`. > > > You're correct, this test does belong here. I think I attached my comment to > the wrong thing (sorry about that). No problems, thanks for the review! https://reviews.llvm.org/D28451 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D28451: [AVR] Add support for the 'interrupt' and 'naked' attributes
dylanmckay marked 4 inline comments as done. dylanmckay added inline comments. Comment at: test/CodeGen/avr/attributes/interrupt.m:4 +// CHECK: define void @_Z3foov() #0 +void foo() __attribute__((interrupt)) { } + aaron.ballman wrote: > This is not an Objective-C method decl, so it doesn't really test anything > new. The test I was envisioning was something like: > ``` > @interface F // There's probably an expected warning here about a missing > base class > -(void) foo __attribute__((interrupt)); > @end > > @implementation F > -(void) foo __attribute__((interrupt)) {} > @end > ``` Removed Obj-C method support. https://reviews.llvm.org/D28451 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D28451: [AVR] Add support for the 'interrupt' and 'naked' attributes
dylanmckay added inline comments. Comment at: lib/Sema/SemaDeclAttr.cpp:5137 + if (!checkAttributeNumArgs(S, Attr, 0)) +Attr.setInvalid(); + aaron.ballman wrote: > This should simply return rather than attempt to attach an invalid attribute > to the declaration (same below). Nice catch Comment at: test/CodeGen/avr/attributes/interrupt.c:3 + +// CHECK: define void @foo() #0 +__attribute__((interrupt)) void foo(void) { } aaron.ballman wrote: > As should this. It seems like this sort of test _does_ sit in `CodeGen` - see `test/CodeGen/{arm-interrupt-attr.c|mips-interrupt-attr.c}`. https://reviews.llvm.org/D28451 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D28451: [AVR] Add support for the 'interrupt' and 'naked' attributes
dylanmckay updated this revision to Diff 87174. dylanmckay marked 2 inline comments as done. dylanmckay added a comment. Code review - Remove support for ObjC methods. We shouldn't do this as it doesn't really make sense - Move some tests to `Sema` - Don't attach invalid attributes when it isn't invalid https://reviews.llvm.org/D28451 Files: include/clang/Basic/Attr.td include/clang/Basic/AttrDocs.td lib/CodeGen/TargetInfo.cpp lib/Sema/SemaDeclAttr.cpp test/CodeGen/avr/attributes/interrupt.c test/CodeGen/avr/attributes/signal.c test/Sema/avr-interrupt-attr.c test/Sema/avr-signal-attr.c Index: test/Sema/avr-signal-attr.c === --- /dev/null +++ test/Sema/avr-signal-attr.c @@ -0,0 +1,8 @@ +// RUN: %clang_cc1 %s -triple avr-unknown-unknown -verify -fsyntax-only +struct a { int b; }; + +struct a test __attribute__((signal)); // expected-warning {{'signal' attribute only applies to functions}} + +__attribute__((signal(12))) void foo(void) { } // expected-error {{'signal' attribute takes no arguments}} + +__attribute__((signal)) void food() {} Index: test/Sema/avr-interrupt-attr.c === --- /dev/null +++ test/Sema/avr-interrupt-attr.c @@ -0,0 +1,8 @@ +// RUN: %clang_cc1 %s -triple avr-unknown-unknown -verify -fsyntax-only +struct a { int b; }; + +struct a test __attribute__((interrupt)); // expected-warning {{'interrupt' attribute only applies to functions}} + +__attribute__((interrupt(12))) void foo(void) { } // expected-error {{'interrupt' attribute takes no arguments}} + +__attribute__((interrupt)) void food() {} Index: test/CodeGen/avr/attributes/signal.c === --- /dev/null +++ test/CodeGen/avr/attributes/signal.c @@ -0,0 +1,6 @@ +// RUN: %clang_cc1 -triple avr-unknown-unknown -emit-llvm %s -o - | FileCheck %s + +// CHECK: define void @foo() #0 +__attribute__((signal)) void foo(void) { } + +// CHECK: attributes #0 = {{{.*signal.*}}} Index: test/CodeGen/avr/attributes/interrupt.c === --- /dev/null +++ test/CodeGen/avr/attributes/interrupt.c @@ -0,0 +1,6 @@ +// RUN: %clang_cc1 -triple avr-unknown-unknown -emit-llvm %s -o - | FileCheck %s + +// CHECK: define void @foo() #0 +__attribute__((interrupt)) void foo(void) { } + +// CHECK: attributes #0 = {{{.*interrupt.*}}} Index: lib/Sema/SemaDeclAttr.cpp === --- lib/Sema/SemaDeclAttr.cpp +++ lib/Sema/SemaDeclAttr.cpp @@ -5126,6 +5126,36 @@ D->addAttr(UsedAttr::CreateImplicit(S.Context)); } +static void handleAVRInterruptAttr(Sema , Decl *D, const AttributeList ) { + if (!isFunctionOrMethod(D)) { +S.Diag(D->getLocation(), diag::warn_attribute_wrong_decl_type) +<< "'interrupt'" << ExpectedFunction; +return; + } + + if (!checkAttributeNumArgs(S, Attr, 0)) { +Attr.setInvalid(); +return; + } + + handleSimpleAttribute(S, D, Attr); +} + +static void handleAVRSignalAttr(Sema , Decl *D, const AttributeList ) { + if (!isFunctionOrMethod(D)) { +S.Diag(D->getLocation(), diag::warn_attribute_wrong_decl_type) +<< "'signal'" << ExpectedFunction; +return; + } + + if (!checkAttributeNumArgs(S, Attr, 0)) { +Attr.setInvalid(); +return; + } + + handleSimpleAttribute(S, D, Attr); +} + static void handleInterruptAttr(Sema , Decl *D, const AttributeList ) { // Dispatch the interrupt attribute based on the current target. switch (S.Context.getTargetInfo().getTriple().getArch()) { @@ -5140,6 +5170,9 @@ 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 +5733,9 @@ case AttributeList::AT_AMDGPUNumVGPR: handleAMDGPUNumVGPRAttr(S, D, Attr); break; + case AttributeList::AT_AVRSignal: +handleAVRSignalAttr(S, D, Attr); +break; case AttributeList::AT_IBAction: handleSimpleAttribute(S, D, Attr); break; Index: lib/CodeGen/TargetInfo.cpp === --- lib/CodeGen/TargetInfo.cpp +++ lib/CodeGen/TargetInfo.cpp @@ -6900,6 +6900,31 @@ } //===--===// +// AVR ABI Implementation. +//===--===// + +namespace { +class AVRTargetCodeGenInfo : public TargetCodeGenInfo { +public: + AVRTargetCodeGenInfo(CodeGenTypes ) +: TargetCodeGenInfo(new DefaultABIInfo(CGT)) { } + + void setTargetAttributes(const Decl *D, llvm::GlobalValue *GV, + CodeGen::CodeGenModule ) const override { +const auto *FD = dyn_cast_or_null(D); +if (!FD) return; +auto *Fn = cast(GV); +
[PATCH] D28451: [AVR] Add support for the 'interrupt' and 'naked' attributes
aaron.ballman added a comment. The new tests aren't really what I had in mind. The codegen tests that should be sema tests can just be rolled into your existing sema tests, by the way. Comment at: lib/Sema/SemaDeclAttr.cpp:5137 + if (!checkAttributeNumArgs(S, Attr, 0)) +Attr.setInvalid(); + This should simply return rather than attempt to attach an invalid attribute to the declaration (same below). Comment at: test/CodeGen/avr/attributes/interrupt-no-args.c:3 + +// CHECK: error: 'interrupt' attribute takes no arguments +__attribute__((interrupt(12))) void foo(void) { } This should be a test in Sema, not in CodeGen. Comment at: test/CodeGen/avr/attributes/interrupt.c:3 + +// CHECK: define void @foo() #0 +__attribute__((interrupt)) void foo(void) { } As should this. Comment at: test/CodeGen/avr/attributes/interrupt.m:1 +// RUN: %clang_cc1 -triple avr-unknown-unknown -x objective-c++ -emit-llvm -o - %s | FileCheck %s + Why objective-c++? Comment at: test/CodeGen/avr/attributes/interrupt.m:4 +// CHECK: define void @_Z3foov() #0 +void foo() __attribute__((interrupt)) { } + This is not an Objective-C method decl, so it doesn't really test anything new. The test I was envisioning was something like: ``` @interface F // There's probably an expected warning here about a missing base class -(void) foo __attribute__((interrupt)); @end @implementation F -(void) foo __attribute__((interrupt)) {} @end ``` Comment at: test/CodeGen/avr/attributes/signal-no-args.c:4 +// CHECK: error: 'signal' attribute takes no arguments +__attribute__((signal(12))) void foo(void) { } This should also be a Sema test. Comment at: test/CodeGen/avr/attributes/signal.m:4 +// CHECK: define void @_Z3foov() #0 +void foo() __attribute__((signal)) { } + Same concerns about this not testing anything new as above. https://reviews.llvm.org/D28451 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D28451: [AVR] Add support for the 'interrupt' and 'naked' attributes
dylanmckay updated this revision to Diff 87164. dylanmckay marked 2 inline comments as done. dylanmckay added a comment. Verify that no arguments are given to the attributes Also adds a bunch of tests. https://reviews.llvm.org/D28451 Files: include/clang/Basic/Attr.td include/clang/Basic/AttrDocs.td lib/CodeGen/TargetInfo.cpp lib/Sema/SemaDeclAttr.cpp test/CodeGen/avr/attributes/interrupt-no-args.c test/CodeGen/avr/attributes/interrupt.c test/CodeGen/avr/attributes/interrupt.m test/CodeGen/avr/attributes/signal-no-args.c test/CodeGen/avr/attributes/signal.c test/CodeGen/avr/attributes/signal.m test/Sema/avr-interrupt-attr.c test/Sema/avr-signal-attr.c Index: test/Sema/avr-signal-attr.c === --- /dev/null +++ test/Sema/avr-signal-attr.c @@ -0,0 +1,6 @@ +// RUN: %clang_cc1 %s -triple avr-unknown-unknown -verify -fsyntax-only +struct a { int b; }; + +struct a test __attribute__((signal)); // expected-warning {{'signal' attribute only applies to functions and methods}} + +__attribute__((signal)) void food() {} Index: test/Sema/avr-interrupt-attr.c === --- /dev/null +++ test/Sema/avr-interrupt-attr.c @@ -0,0 +1,6 @@ +// RUN: %clang_cc1 %s -triple avr-unknown-unknown -verify -fsyntax-only +struct a { int b; }; + +struct a test __attribute__((interrupt)); // expected-warning {{'interrupt' attribute only applies to functions and methods}} + +__attribute__((interrupt)) void food() {} Index: test/CodeGen/avr/attributes/signal.m === --- /dev/null +++ test/CodeGen/avr/attributes/signal.m @@ -0,0 +1,6 @@ +// RUN: %clang_cc1 -triple avr-unknown-unknown -x objective-c++ -emit-llvm -o - %s | FileCheck %s + +// CHECK: define void @_Z3foov() #0 +void foo() __attribute__((signal)) { } + +// CHECK: attributes #0 = {{{.*signal.*}}} Index: test/CodeGen/avr/attributes/signal.c === --- /dev/null +++ test/CodeGen/avr/attributes/signal.c @@ -0,0 +1,6 @@ +// RUN: %clang_cc1 -triple avr-unknown-unknown -emit-llvm %s -o - | FileCheck %s + +// CHECK: define void @foo() #0 +__attribute__((signal)) void foo(void) { } + +// CHECK: attributes #0 = {{{.*signal.*}}} Index: test/CodeGen/avr/attributes/signal-no-args.c === --- /dev/null +++ test/CodeGen/avr/attributes/signal-no-args.c @@ -0,0 +1,4 @@ +// RUN: not %clang_cc1 -triple avr-unknown-unknown -emit-llvm %s -o - 2>&1 | FileCheck %s + +// CHECK: error: 'signal' attribute takes no arguments +__attribute__((signal(12))) void foo(void) { } Index: test/CodeGen/avr/attributes/interrupt.m === --- /dev/null +++ test/CodeGen/avr/attributes/interrupt.m @@ -0,0 +1,6 @@ +// RUN: %clang_cc1 -triple avr-unknown-unknown -x objective-c++ -emit-llvm -o - %s | FileCheck %s + +// CHECK: define void @_Z3foov() #0 +void foo() __attribute__((interrupt)) { } + +// CHECK: attributes #0 = {{{.*interrupt.*}}} Index: test/CodeGen/avr/attributes/interrupt.c === --- /dev/null +++ test/CodeGen/avr/attributes/interrupt.c @@ -0,0 +1,6 @@ +// RUN: %clang_cc1 -triple avr-unknown-unknown -emit-llvm %s -o - | FileCheck %s + +// CHECK: define void @foo() #0 +__attribute__((interrupt)) void foo(void) { } + +// CHECK: attributes #0 = {{{.*interrupt.*}}} Index: test/CodeGen/avr/attributes/interrupt-no-args.c === --- /dev/null +++ test/CodeGen/avr/attributes/interrupt-no-args.c @@ -0,0 +1,4 @@ +// RUN: not %clang_cc1 -triple avr-unknown-unknown -emit-llvm %s -o - 2>&1 | FileCheck %s + +// CHECK: error: 'interrupt' attribute takes no arguments +__attribute__((interrupt(12))) void foo(void) { } Index: lib/Sema/SemaDeclAttr.cpp === --- lib/Sema/SemaDeclAttr.cpp +++ lib/Sema/SemaDeclAttr.cpp @@ -5126,6 +5126,32 @@ D->addAttr(UsedAttr::CreateImplicit(S.Context)); } +static void handleAVRInterruptAttr(Sema , Decl *D, const AttributeList ) { + if (!isFunctionOrMethod(D)) { +S.Diag(D->getLocation(), diag::warn_attribute_wrong_decl_type) +<< "'interrupt'" << ExpectedFunctionOrMethod; +return; + } + + if (!checkAttributeNumArgs(S, Attr, 0)) +Attr.setInvalid(); + + handleSimpleAttribute(S, D, Attr); +} + +static void handleAVRSignalAttr(Sema , Decl *D, const AttributeList ) { + if (!isFunctionOrMethod(D)) { +S.Diag(D->getLocation(), diag::warn_attribute_wrong_decl_type) +<< "'signal'" << ExpectedFunctionOrMethod; +return; + } + + if (!checkAttributeNumArgs(S, Attr, 0)) +Attr.setInvalid(); + + handleSimpleAttribute(S, D, Attr); +} + static void handleInterruptAttr(Sema , Decl *D, const
[PATCH] D28451: [AVR] Add support for the 'interrupt' and 'naked' attributes
aaron.ballman added a comment. Just one more issue due to the nature of needing a custom parsed attribute. Comment at: lib/Sema/SemaDeclAttr.cpp:5130 +static void handleAVRInterruptAttr(Sema , Decl *D, const AttributeList ) { + if (!isFunctionOrMethod(D)) { +S.Diag(D->getLocation(), diag::warn_attribute_wrong_decl_type) Because you have to do custom parsing, you also need to manually check that the attribute was not given any arguments and diagnose if they are present. Comment at: test/Sema/avr-interrupt-attr.c:5 +struct a test __attribute__((interrupt)); // expected-warning {{'interrupt' attribute only applies to functions and methods}} + +__attribute__((interrupt)) void food() {} Please add a test for `__attribute__((interrupt(12)))`, and a test with an Objective-C method. Similar for `signal`. You should add an ObjC method to the codegen tests as well. https://reviews.llvm.org/D28451 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D28451: [AVR] Add support for the 'interrupt' and 'naked' attributes
dylanmckay updated this revision to Diff 87054. dylanmckay marked 5 inline comments as done. dylanmckay added a comment. Code review comments - Add 'Subjects = [ObjCMethod]' to attributes - Use 'auto' keyword in one place - Move complex attr parsing logic into static function https://reviews.llvm.org/D28451 Files: include/clang/Basic/Attr.td include/clang/Basic/AttrDocs.td lib/CodeGen/TargetInfo.cpp lib/Sema/SemaDeclAttr.cpp test/CodeGen/avr/attributes/interrupt.c test/CodeGen/avr/attributes/signal.c test/Sema/avr-interrupt-attr.c test/Sema/avr-signal-attr.c Index: test/Sema/avr-signal-attr.c === --- /dev/null +++ test/Sema/avr-signal-attr.c @@ -0,0 +1,6 @@ +// RUN: %clang_cc1 %s -triple avr-unknown-unknown -verify -fsyntax-only +struct a { int b; }; + +struct a test __attribute__((signal)); // expected-warning {{'signal' attribute only applies to functions and methods}} + +__attribute__((signal)) void food() {} Index: test/Sema/avr-interrupt-attr.c === --- /dev/null +++ test/Sema/avr-interrupt-attr.c @@ -0,0 +1,6 @@ +// RUN: %clang_cc1 %s -triple avr-unknown-unknown -verify -fsyntax-only +struct a { int b; }; + +struct a test __attribute__((interrupt)); // expected-warning {{'interrupt' attribute only applies to functions and methods}} + +__attribute__((interrupt)) void food() {} Index: test/CodeGen/avr/attributes/signal.c === --- /dev/null +++ test/CodeGen/avr/attributes/signal.c @@ -0,0 +1,6 @@ +// RUN: %clang_cc1 -triple avr-unknown-unknown -emit-llvm %s -o - | FileCheck %s + +// CHECK: define void @foo() #0 +__attribute__((signal)) void foo(void) { } + +// CHECK: attributes #0 = {{{.*signal.*}}} Index: test/CodeGen/avr/attributes/interrupt.c === --- /dev/null +++ test/CodeGen/avr/attributes/interrupt.c @@ -0,0 +1,6 @@ +// RUN: %clang_cc1 -triple avr-unknown-unknown -emit-llvm %s -o - | FileCheck %s + +// CHECK: define void @foo() #0 +__attribute__((interrupt)) void foo(void) { } + +// CHECK: attributes #0 = {{{.*interrupt.*}}} Index: lib/Sema/SemaDeclAttr.cpp === --- lib/Sema/SemaDeclAttr.cpp +++ lib/Sema/SemaDeclAttr.cpp @@ -5126,6 +5126,26 @@ D->addAttr(UsedAttr::CreateImplicit(S.Context)); } +static void handleAVRInterruptAttr(Sema , Decl *D, const AttributeList ) { + if (!isFunctionOrMethod(D)) { +S.Diag(D->getLocation(), diag::warn_attribute_wrong_decl_type) +<< "'interrupt'" << ExpectedFunctionOrMethod; +return; + } + + handleSimpleAttribute(S, D, Attr); +} + +static void handleAVRSignalAttr(Sema , Decl *D, const AttributeList ) { + if (!isFunctionOrMethod(D)) { +S.Diag(D->getLocation(), diag::warn_attribute_wrong_decl_type) +<< "'signal'" << ExpectedFunctionOrMethod; +return; + } + + handleSimpleAttribute(S, D, Attr); +} + static void handleInterruptAttr(Sema , Decl *D, const AttributeList ) { // Dispatch the interrupt attribute based on the current target. switch (S.Context.getTargetInfo().getTriple().getArch()) { @@ -5140,6 +5160,9 @@ 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 +5723,9 @@ case AttributeList::AT_AMDGPUNumVGPR: handleAMDGPUNumVGPRAttr(S, D, Attr); break; + case AttributeList::AT_AVRSignal: +handleAVRSignalAttr(S, D, Attr); +break; case AttributeList::AT_IBAction: handleSimpleAttribute(S, D, Attr); break; Index: lib/CodeGen/TargetInfo.cpp === --- lib/CodeGen/TargetInfo.cpp +++ lib/CodeGen/TargetInfo.cpp @@ -6900,6 +6900,31 @@ } //===--===// +// AVR ABI Implementation. +//===--===// + +namespace { +class AVRTargetCodeGenInfo : public TargetCodeGenInfo { +public: + AVRTargetCodeGenInfo(CodeGenTypes ) +: TargetCodeGenInfo(new DefaultABIInfo(CGT)) { } + + void setTargetAttributes(const Decl *D, llvm::GlobalValue *GV, + CodeGen::CodeGenModule ) const override { +const auto *FD = dyn_cast_or_null(D); +if (!FD) return; +auto *Fn = cast(GV); + +if (FD->getAttr()) + Fn->addFnAttr("interrupt"); + +if (FD->getAttr()) + 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. @@
[PATCH] D28451: [AVR] Add support for the 'interrupt' and 'naked' attributes
aaron.ballman added inline comments. Comment at: lib/Sema/SemaDeclAttr.cpp:5158 + case llvm::Triple::avr: +handleAVRInterruptAttr(S, D, Attr); +break; aaron.ballman wrote: > Just call `handleSimpleAttribute()` instead. Since this is no longer truly a simple attribute (it requires some custom checking), I think my earlier advice was wrong -- you should split this into a `handleAVRInterruptAttr()` method. I forgot that you need the custom checking because the attribute has custom parsing. Comment at: lib/Sema/SemaDeclAttr.cpp:5721 + case AttributeList::AT_AVRSignal: +handleAVRSignalAttr(S, D, Attr); +break; aaron.ballman wrote: > ...same here. ... same here. Comment at: lib/Sema/SemaDeclAttr.cpp:5145 +if (!isFunctionOrMethod(D)) { + S.Diag(D->getLocation(), diag::warn_attribute_wrong_decl_type) + << "'interrupt'" << ExpectedFunctionOrMethod; dylanmckay wrote: > I'm pretty sure that this check shouldn't be necessary, because we define > `Subjects = [Function]` in TableGen. > > Without it though, the warning doesn't appear. Do you know why that is > @aaron.ballman? It's because it requires custom parsing. Comment at: lib/Sema/SemaDeclAttr.cpp:5146 + S.Diag(D->getLocation(), diag::warn_attribute_wrong_decl_type) + << "'interrupt'" << ExpectedFunctionOrMethod; + return; The diagnostic and the predicate for it don't match your `Subjects` line. Should this appertain to ObjC methods? If not, you want to use `ExpectedFunction` instead. If so, you want to add `ObjCMethod` to the `Subjects` line. https://reviews.llvm.org/D28451 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D28451: [AVR] Add support for the 'interrupt' and 'naked' attributes
malcolm.parsons added inline comments. Comment at: lib/CodeGen/TargetInfo.cpp:6916 +if (!FD) return; +llvm::Function *Fn = cast(GV); + You can use `auto *` here too. https://reviews.llvm.org/D28451 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D28451: [AVR] Add support for the 'interrupt' and 'naked' attributes
dylanmckay added inline comments. Comment at: lib/Sema/SemaDeclAttr.cpp:5145 +if (!isFunctionOrMethod(D)) { + S.Diag(D->getLocation(), diag::warn_attribute_wrong_decl_type) + << "'interrupt'" << ExpectedFunctionOrMethod; I'm pretty sure that this check shouldn't be necessary, because we define `Subjects = [Function]` in TableGen. Without it though, the warning doesn't appear. Do you know why that is @aaron.ballman? https://reviews.llvm.org/D28451 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D28451: [AVR] Add support for the 'interrupt' and 'naked' attributes
dylanmckay updated this revision to Diff 85053. dylanmckay added a comment. Add 'Subjects' field to 'AVRSignal' https://reviews.llvm.org/D28451 Files: include/clang/Basic/Attr.td include/clang/Basic/AttrDocs.td lib/CodeGen/TargetInfo.cpp lib/Sema/SemaDeclAttr.cpp test/CodeGen/avr/attributes/interrupt.c test/CodeGen/avr/attributes/signal.c test/Sema/avr-interrupt-attr.c test/Sema/avr-signal-attr.c Index: test/Sema/avr-signal-attr.c === --- /dev/null +++ test/Sema/avr-signal-attr.c @@ -0,0 +1,6 @@ +// RUN: %clang_cc1 %s -triple avr-unknown-unknown -verify -fsyntax-only +struct a { int b; }; + +struct a test __attribute__((signal)); // expected-warning {{'signal' attribute only applies to functions and methods}} + +__attribute__((signal)) void food() {} Index: test/Sema/avr-interrupt-attr.c === --- /dev/null +++ test/Sema/avr-interrupt-attr.c @@ -0,0 +1,6 @@ +// RUN: %clang_cc1 %s -triple avr-unknown-unknown -verify -fsyntax-only +struct a { int b; }; + +struct a test __attribute__((interrupt)); // expected-warning {{'interrupt' attribute only applies to functions and methods}} + +__attribute__((interrupt)) void food() {} Index: test/CodeGen/avr/attributes/signal.c === --- /dev/null +++ test/CodeGen/avr/attributes/signal.c @@ -0,0 +1,6 @@ +// RUN: %clang_cc1 -triple avr-unknown-unknown -emit-llvm %s -o - | FileCheck %s + +// CHECK: define void @foo() #0 +__attribute__((signal)) void foo(void) { } + +// CHECK: attributes #0 = {{{.*signal.*}}} Index: test/CodeGen/avr/attributes/interrupt.c === --- /dev/null +++ test/CodeGen/avr/attributes/interrupt.c @@ -0,0 +1,6 @@ +// RUN: %clang_cc1 -triple avr-unknown-unknown -emit-llvm %s -o - | FileCheck %s + +// CHECK: define void @foo() #0 +__attribute__((interrupt)) void foo(void) { } + +// CHECK: attributes #0 = {{{.*interrupt.*}}} Index: lib/Sema/SemaDeclAttr.cpp === --- lib/Sema/SemaDeclAttr.cpp +++ lib/Sema/SemaDeclAttr.cpp @@ -5140,6 +5140,15 @@ case llvm::Triple::x86_64: handleAnyX86InterruptAttr(S, D, Attr); break; + case llvm::Triple::avr: +if (!isFunctionOrMethod(D)) { + S.Diag(D->getLocation(), diag::warn_attribute_wrong_decl_type) + << "'interrupt'" << ExpectedFunctionOrMethod; + return; +} + +handleSimpleAttribute(S, D, Attr); +break; default: handleARMInterruptAttr(S, D, Attr); break; @@ -5700,6 +5709,14 @@ case AttributeList::AT_AMDGPUNumVGPR: handleAMDGPUNumVGPRAttr(S, D, Attr); break; + case AttributeList::AT_AVRSignal: +if (!isFunctionOrMethod(D)) { + S.Diag(D->getLocation(), diag::warn_attribute_wrong_decl_type) + << "'signal'" << ExpectedFunctionOrMethod; + return; +} +handleSimpleAttribute(S, D, Attr); +break; case AttributeList::AT_IBAction: handleSimpleAttribute(S, D, Attr); break; Index: lib/CodeGen/TargetInfo.cpp === --- lib/CodeGen/TargetInfo.cpp +++ lib/CodeGen/TargetInfo.cpp @@ -6900,6 +6900,31 @@ } //===--===// +// AVR ABI Implementation. +//===--===// + +namespace { +class AVRTargetCodeGenInfo : public TargetCodeGenInfo { +public: + AVRTargetCodeGenInfo(CodeGenTypes ) +: TargetCodeGenInfo(new DefaultABIInfo(CGT)) { } + + void setTargetAttributes(const Decl *D, llvm::GlobalValue *GV, + CodeGen::CodeGenModule ) const override { +const auto *FD = dyn_cast_or_null(D); +if (!FD) return; +llvm::Function *Fn = cast(GV); + +if (FD->getAttr()) + Fn->addFnAttr("interrupt"); + +if (FD->getAttr()) + 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 @@ 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; Index: include/clang/Basic/AttrDocs.td === --- include/clang/Basic/AttrDocs.td +++ include/clang/Basic/AttrDocs.td @@ -1182,6 +1182,33 @@ }]; } +def AVRInterruptDocs : Documentation { + let Category = DocCatFunction; + let Content = [{ +Clang supports the
[PATCH] D28451: [AVR] Add support for the 'interrupt' and 'naked' attributes
dylanmckay updated this revision to Diff 85052. dylanmckay added a comment. Remove a test for the 'naked' attribute https://reviews.llvm.org/D28451 Files: include/clang/Basic/Attr.td include/clang/Basic/AttrDocs.td lib/CodeGen/TargetInfo.cpp lib/Sema/SemaDeclAttr.cpp test/CodeGen/avr/attributes/interrupt.c test/CodeGen/avr/attributes/signal.c test/Sema/avr-interrupt-attr.c test/Sema/avr-signal-attr.c Index: test/Sema/avr-signal-attr.c === --- /dev/null +++ test/Sema/avr-signal-attr.c @@ -0,0 +1,6 @@ +// RUN: %clang_cc1 %s -triple avr-unknown-unknown -verify -fsyntax-only +struct a { int b; }; + +struct a test __attribute__((signal)); // expected-warning {{'signal' attribute only applies to functions and methods}} + +__attribute__((signal)) void food() {} Index: test/Sema/avr-interrupt-attr.c === --- /dev/null +++ test/Sema/avr-interrupt-attr.c @@ -0,0 +1,6 @@ +// RUN: %clang_cc1 %s -triple avr-unknown-unknown -verify -fsyntax-only +struct a { int b; }; + +struct a test __attribute__((interrupt)); // expected-warning {{'interrupt' attribute only applies to functions and methods}} + +__attribute__((interrupt)) void food() {} Index: test/CodeGen/avr/attributes/signal.c === --- /dev/null +++ test/CodeGen/avr/attributes/signal.c @@ -0,0 +1,6 @@ +// RUN: %clang_cc1 -triple avr-unknown-unknown -emit-llvm %s -o - | FileCheck %s + +// CHECK: define void @foo() #0 +__attribute__((signal)) void foo(void) { } + +// CHECK: attributes #0 = {{{.*signal.*}}} Index: test/CodeGen/avr/attributes/interrupt.c === --- /dev/null +++ test/CodeGen/avr/attributes/interrupt.c @@ -0,0 +1,6 @@ +// RUN: %clang_cc1 -triple avr-unknown-unknown -emit-llvm %s -o - | FileCheck %s + +// CHECK: define void @foo() #0 +__attribute__((interrupt)) void foo(void) { } + +// CHECK: attributes #0 = {{{.*interrupt.*}}} Index: lib/Sema/SemaDeclAttr.cpp === --- lib/Sema/SemaDeclAttr.cpp +++ lib/Sema/SemaDeclAttr.cpp @@ -5140,6 +5140,15 @@ case llvm::Triple::x86_64: handleAnyX86InterruptAttr(S, D, Attr); break; + case llvm::Triple::avr: +if (!isFunctionOrMethod(D)) { + S.Diag(D->getLocation(), diag::warn_attribute_wrong_decl_type) + << "'interrupt'" << ExpectedFunctionOrMethod; + return; +} + +handleSimpleAttribute(S, D, Attr); +break; default: handleARMInterruptAttr(S, D, Attr); break; @@ -5700,6 +5709,14 @@ case AttributeList::AT_AMDGPUNumVGPR: handleAMDGPUNumVGPRAttr(S, D, Attr); break; + case AttributeList::AT_AVRSignal: +if (!isFunctionOrMethod(D)) { + S.Diag(D->getLocation(), diag::warn_attribute_wrong_decl_type) + << "'signal'" << ExpectedFunctionOrMethod; + return; +} +handleSimpleAttribute(S, D, Attr); +break; case AttributeList::AT_IBAction: handleSimpleAttribute(S, D, Attr); break; Index: lib/CodeGen/TargetInfo.cpp === --- lib/CodeGen/TargetInfo.cpp +++ lib/CodeGen/TargetInfo.cpp @@ -6900,6 +6900,31 @@ } //===--===// +// AVR ABI Implementation. +//===--===// + +namespace { +class AVRTargetCodeGenInfo : public TargetCodeGenInfo { +public: + AVRTargetCodeGenInfo(CodeGenTypes ) +: TargetCodeGenInfo(new DefaultABIInfo(CGT)) { } + + void setTargetAttributes(const Decl *D, llvm::GlobalValue *GV, + CodeGen::CodeGenModule ) const override { +const auto *FD = dyn_cast_or_null(D); +if (!FD) return; +llvm::Function *Fn = cast(GV); + +if (FD->getAttr()) + Fn->addFnAttr("interrupt"); + +if (FD->getAttr()) + 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 @@ 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; Index: include/clang/Basic/AttrDocs.td === --- include/clang/Basic/AttrDocs.td +++ include/clang/Basic/AttrDocs.td @@ -1182,6 +1182,33 @@ }]; } +def AVRInterruptDocs : Documentation { + let Category = DocCatFunction; + let Content = [{ +Clang supports
[PATCH] D28451: [AVR] Add support for the 'interrupt' and 'naked' attributes
dylanmckay updated this revision to Diff 85051. dylanmckay marked 5 inline comments as done. dylanmckay added a comment. Code review from Aaron - Use 'handleSimpleAttribute' rather than duplicating it - Use 'auto' where a type is explicitly casted - Add warnings for when the attribute is not on a function - Add sema tests for when the attr is not on a function https://reviews.llvm.org/D28451 Files: include/clang/Basic/Attr.td include/clang/Basic/AttrDocs.td lib/CodeGen/TargetInfo.cpp lib/Sema/SemaDeclAttr.cpp test/CodeGen/avr/attributes/interrupt.c test/CodeGen/avr/attributes/naked.c test/CodeGen/avr/attributes/signal.c test/Sema/avr-interrupt-attr.c test/Sema/avr-signal-attr.c Index: test/Sema/avr-signal-attr.c === --- /dev/null +++ test/Sema/avr-signal-attr.c @@ -0,0 +1,6 @@ +// RUN: %clang_cc1 %s -triple avr-unknown-unknown -verify -fsyntax-only +struct a { int b; }; + +struct a test __attribute__((signal)); // expected-warning {{'signal' attribute only applies to functions and methods}} + +__attribute__((signal)) void food() {} Index: test/Sema/avr-interrupt-attr.c === --- /dev/null +++ test/Sema/avr-interrupt-attr.c @@ -0,0 +1,6 @@ +// RUN: %clang_cc1 %s -triple avr-unknown-unknown -verify -fsyntax-only +struct a { int b; }; + +struct a test __attribute__((interrupt)); // expected-warning {{'interrupt' attribute only applies to functions and methods}} + +__attribute__((interrupt)) void food() {} Index: test/CodeGen/avr/attributes/signal.c === --- /dev/null +++ test/CodeGen/avr/attributes/signal.c @@ -0,0 +1,6 @@ +// RUN: %clang_cc1 -triple avr-unknown-unknown -emit-llvm %s -o - | FileCheck %s + +// CHECK: define void @foo() #0 +__attribute__((signal)) void foo(void) { } + +// CHECK: attributes #0 = {{{.*signal.*}}} Index: test/CodeGen/avr/attributes/naked.c === --- /dev/null +++ test/CodeGen/avr/attributes/naked.c @@ -0,0 +1,6 @@ +// RUN: %clang_cc1 -triple avr-unknown-unknown -emit-llvm %s -o - | FileCheck %s + +// CHECK: define void @foo() #0 +__attribute__((naked)) void foo(void) { } + +// CHECK: attributes #0 = {{{.*naked.*}}} Index: test/CodeGen/avr/attributes/interrupt.c === --- /dev/null +++ test/CodeGen/avr/attributes/interrupt.c @@ -0,0 +1,6 @@ +// RUN: %clang_cc1 -triple avr-unknown-unknown -emit-llvm %s -o - | FileCheck %s + +// CHECK: define void @foo() #0 +__attribute__((interrupt)) void foo(void) { } + +// CHECK: attributes #0 = {{{.*interrupt.*}}} Index: lib/Sema/SemaDeclAttr.cpp === --- lib/Sema/SemaDeclAttr.cpp +++ lib/Sema/SemaDeclAttr.cpp @@ -5140,6 +5140,15 @@ case llvm::Triple::x86_64: handleAnyX86InterruptAttr(S, D, Attr); break; + case llvm::Triple::avr: +if (!isFunctionOrMethod(D)) { + S.Diag(D->getLocation(), diag::warn_attribute_wrong_decl_type) + << "'interrupt'" << ExpectedFunctionOrMethod; + return; +} + +handleSimpleAttribute(S, D, Attr); +break; default: handleARMInterruptAttr(S, D, Attr); break; @@ -5700,6 +5709,14 @@ case AttributeList::AT_AMDGPUNumVGPR: handleAMDGPUNumVGPRAttr(S, D, Attr); break; + case AttributeList::AT_AVRSignal: +if (!isFunctionOrMethod(D)) { + S.Diag(D->getLocation(), diag::warn_attribute_wrong_decl_type) + << "'signal'" << ExpectedFunctionOrMethod; + return; +} +handleSimpleAttribute(S, D, Attr); +break; case AttributeList::AT_IBAction: handleSimpleAttribute(S, D, Attr); break; Index: lib/CodeGen/TargetInfo.cpp === --- lib/CodeGen/TargetInfo.cpp +++ lib/CodeGen/TargetInfo.cpp @@ -6900,6 +6900,31 @@ } //===--===// +// AVR ABI Implementation. +//===--===// + +namespace { +class AVRTargetCodeGenInfo : public TargetCodeGenInfo { +public: + AVRTargetCodeGenInfo(CodeGenTypes ) +: TargetCodeGenInfo(new DefaultABIInfo(CGT)) { } + + void setTargetAttributes(const Decl *D, llvm::GlobalValue *GV, + CodeGen::CodeGenModule ) const override { +const auto *FD = dyn_cast_or_null(D); +if (!FD) return; +llvm::Function *Fn = cast(GV); + +if (FD->getAttr()) + Fn->addFnAttr("interrupt"); + +if (FD->getAttr()) + 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
[PATCH] D28451: [AVR] Add support for the 'interrupt' and 'naked' attributes
aaron.ballman added inline comments. Comment at: include/clang/Basic/Attr.td:488 + +def AVRSignal : InheritableAttr, TargetSpecificAttr { + let Spellings = [GNU<"signal">]; dylanmckay wrote: > aaron.ballman wrote: > > Does this attribute appertain to any specific subjects, or can you apply it > > to any declaration? > It can be applied to function definitions only. Then it should have a Subjects line like `AVRInterrupt` does. Comment at: lib/CodeGen/TargetInfo.cpp:6898 + CodeGen::CodeGenModule ) const override { +const FunctionDecl *FD = dyn_cast_or_null(D); +if (!FD) return; You can use `const auto *` here. Comment at: lib/Sema/SemaDeclAttr.cpp:5129 +static void handleAVRInterruptAttr(Sema , Decl *D, + const AttributeList ) { You can remove this function. Comment at: lib/Sema/SemaDeclAttr.cpp:5136 + +static void handleAVRSignalAttr(Sema , Decl *D, +const AttributeList ) { ...and this one. Comment at: lib/Sema/SemaDeclAttr.cpp:5158 + case llvm::Triple::avr: +handleAVRInterruptAttr(S, D, Attr); +break; Just call `handleSimpleAttribute()` instead. Comment at: lib/Sema/SemaDeclAttr.cpp:5721 + case AttributeList::AT_AVRSignal: +handleAVRSignalAttr(S, D, Attr); +break; ...same here. Comment at: test/CodeGen/avr/attributes/naked.c:4 +// CHECK: define void @foo() #0 +__attribute__((naked)) void foo(void) { } + dylanmckay wrote: > aaron.ballman wrote: > > This test seems unrelated as you didn't modify anything about the naked > > attribute? > I didn't modify the naked attribute, but I did want to include a test for AVR. This should probably be a separate commit then (and doesn't really need code review, since it's just adding a test and is otherwise NFC); just make sure the commit message explains why the test is beneficial to add. https://reviews.llvm.org/D28451 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D28451: [AVR] Add support for the 'interrupt' and 'naked' attributes
dylanmckay added inline comments. Comment at: include/clang/Basic/Attr.td:488 + +def AVRSignal : InheritableAttr, TargetSpecificAttr { + let Spellings = [GNU<"signal">]; aaron.ballman wrote: > Does this attribute appertain to any specific subjects, or can you apply it > to any declaration? It can be applied to function definitions only. Comment at: test/CodeGen/avr/attributes/naked.c:4 +// CHECK: define void @foo() #0 +__attribute__((naked)) void foo(void) { } + aaron.ballman wrote: > This test seems unrelated as you didn't modify anything about the naked > attribute? I didn't modify the naked attribute, but I did want to include a test for AVR. https://reviews.llvm.org/D28451 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D28451: [AVR] Add support for the 'interrupt' and 'naked' attributes
dylanmckay updated this revision to Diff 83913. dylanmckay marked 2 inline comments as done. dylanmckay added a comment. [AVR] Document the 'interrupt' and 'naked' attributes https://reviews.llvm.org/D28451 Files: include/clang/Basic/Attr.td include/clang/Basic/AttrDocs.td lib/CodeGen/TargetInfo.cpp lib/Sema/SemaDeclAttr.cpp test/CodeGen/avr/attributes/interrupt.c test/CodeGen/avr/attributes/naked.c test/CodeGen/avr/attributes/signal.c Index: test/CodeGen/avr/attributes/signal.c === --- /dev/null +++ test/CodeGen/avr/attributes/signal.c @@ -0,0 +1,6 @@ +// RUN: %clang_cc1 -triple avr-unknown-unknown -emit-llvm %s -o - | FileCheck %s + +// CHECK: define void @foo() #0 +__attribute__((signal)) void foo(void) { } + +// CHECK: attributes #0 = {{{.*signal.*}}} Index: test/CodeGen/avr/attributes/naked.c === --- /dev/null +++ test/CodeGen/avr/attributes/naked.c @@ -0,0 +1,6 @@ +// RUN: %clang_cc1 -triple avr-unknown-unknown -emit-llvm %s -o - | FileCheck %s + +// CHECK: define void @foo() #0 +__attribute__((naked)) void foo(void) { } + +// CHECK: attributes #0 = {{{.*naked.*}}} Index: test/CodeGen/avr/attributes/interrupt.c === --- /dev/null +++ test/CodeGen/avr/attributes/interrupt.c @@ -0,0 +1,6 @@ +// RUN: %clang_cc1 -triple avr-unknown-unknown -emit-llvm %s -o - | FileCheck %s + +// CHECK: define void @foo() #0 +__attribute__((interrupt)) void foo(void) { } + +// CHECK: attributes #0 = {{{.*interrupt.*}}} Index: lib/Sema/SemaDeclAttr.cpp === --- lib/Sema/SemaDeclAttr.cpp +++ lib/Sema/SemaDeclAttr.cpp @@ -5126,6 +5126,20 @@ D->addAttr(UsedAttr::CreateImplicit(S.Context)); } +static void handleAVRInterruptAttr(Sema , Decl *D, + const AttributeList ) { + D->addAttr(::new (S.Context) + AVRInterruptAttr(Attr.getLoc(), S.Context, + Attr.getAttributeSpellingListIndex())); +} + +static void handleAVRSignalAttr(Sema , Decl *D, +const AttributeList ) { + D->addAttr(::new (S.Context) + AVRSignalAttr(Attr.getLoc(), S.Context, + Attr.getAttributeSpellingListIndex())); +} + static void handleInterruptAttr(Sema , Decl *D, const AttributeList ) { // Dispatch the interrupt attribute based on the current target. switch (S.Context.getTargetInfo().getTriple().getArch()) { @@ -5140,6 +5154,9 @@ 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 +5717,9 @@ case AttributeList::AT_AMDGPUNumVGPR: handleAMDGPUNumVGPRAttr(S, D, Attr); break; + case AttributeList::AT_AVRSignal: +handleAVRSignalAttr(S, D, Attr); +break; case AttributeList::AT_IBAction: handleSimpleAttribute(S, D, Attr); break; Index: lib/CodeGen/TargetInfo.cpp === --- lib/CodeGen/TargetInfo.cpp +++ lib/CodeGen/TargetInfo.cpp @@ -6884,6 +6884,31 @@ } //===--===// +// AVR ABI Implementation. +//===--===// + +namespace { +class AVRTargetCodeGenInfo : public TargetCodeGenInfo { +public: + AVRTargetCodeGenInfo(CodeGenTypes ) +: TargetCodeGenInfo(new DefaultABIInfo(CGT)) { } + + void setTargetAttributes(const Decl *D, llvm::GlobalValue *GV, + CodeGen::CodeGenModule ) const override { +const FunctionDecl *FD = dyn_cast_or_null(D); +if (!FD) return; +llvm::Function *Fn = cast(GV); + +if (FD->getAttr()) + Fn->addFnAttr("interrupt"); + +if (FD->getAttr()) + 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. @@ -8386,6 +8411,9 @@ 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; Index: include/clang/Basic/AttrDocs.td === --- include/clang/Basic/AttrDocs.td +++ include/clang/Basic/AttrDocs.td @@ -1181,6 +1181,33 @@ }]; } +def AVRInterruptDocs : Documentation { + let Category = DocCatFunction; + let Content =
[PATCH] D28451: [AVR] Add support for the 'interrupt' and 'naked' attributes
aaron.ballman requested changes to this revision. aaron.ballman added a comment. This revision now requires changes to proceed. The patch is also missing Sema tests that ensure the attributes are properly diagnosed when applied to something other than a function, a target other than AVR, arguments are present, etc. Comment at: include/clang/Basic/Attr.td:485 + let ParseKind = "Interrupt"; + let Documentation = [Undocumented]; +} No new undocumented attributes, please. Comment at: include/clang/Basic/Attr.td:488 + +def AVRSignal : InheritableAttr, TargetSpecificAttr { + let Spellings = [GNU<"signal">]; Does this attribute appertain to any specific subjects, or can you apply it to any declaration? Comment at: include/clang/Basic/Attr.td:490 + let Spellings = [GNU<"signal">]; + let Documentation = [Undocumented]; +} No new undocumented attributes, please. Comment at: test/CodeGen/avr/attributes/naked.c:4 +// CHECK: define void @foo() #0 +__attribute__((naked)) void foo(void) { } + This test seems unrelated as you didn't modify anything about the naked attribute? https://reviews.llvm.org/D28451 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D28451: [AVR] Add support for the 'interrupt' and 'naked' attributes
dylanmckay updated this revision to Diff 83544. dylanmckay added a comment. Lower the 'signal' attribute correctly I had forgotten to lower this attribute and so it would not have been lowered to IR at all. Now it works fine. https://reviews.llvm.org/D28451 Files: include/clang/Basic/Attr.td lib/CodeGen/TargetInfo.cpp lib/Sema/SemaDeclAttr.cpp test/CodeGen/avr/attributes/interrupt.c test/CodeGen/avr/attributes/naked.c test/CodeGen/avr/attributes/signal.c Index: test/CodeGen/avr/attributes/signal.c === --- /dev/null +++ test/CodeGen/avr/attributes/signal.c @@ -0,0 +1,6 @@ +// RUN: %clang_cc1 -triple avr-unknown-unknown -emit-llvm %s -o - | FileCheck %s + +// CHECK: define void @foo() #0 +__attribute__((signal)) void foo(void) { } + +// CHECK: attributes #0 = {{{.*signal.*}}} Index: test/CodeGen/avr/attributes/naked.c === --- /dev/null +++ test/CodeGen/avr/attributes/naked.c @@ -0,0 +1,6 @@ +// RUN: %clang_cc1 -triple avr-unknown-unknown -emit-llvm %s -o - | FileCheck %s + +// CHECK: define void @foo() #0 +__attribute__((naked)) void foo(void) { } + +// CHECK: attributes #0 = {{{.*naked.*}}} Index: test/CodeGen/avr/attributes/interrupt.c === --- /dev/null +++ test/CodeGen/avr/attributes/interrupt.c @@ -0,0 +1,6 @@ +// RUN: %clang_cc1 -triple avr-unknown-unknown -emit-llvm %s -o - | FileCheck %s + +// CHECK: define void @foo() #0 +__attribute__((interrupt)) void foo(void) { } + +// CHECK: attributes #0 = {{{.*interrupt.*}}} Index: lib/Sema/SemaDeclAttr.cpp === --- lib/Sema/SemaDeclAttr.cpp +++ lib/Sema/SemaDeclAttr.cpp @@ -5042,6 +5042,20 @@ D->addAttr(UsedAttr::CreateImplicit(S.Context)); } +static void handleAVRInterruptAttr(Sema , Decl *D, + const AttributeList ) { + D->addAttr(::new (S.Context) + AVRInterruptAttr(Attr.getLoc(), S.Context, + Attr.getAttributeSpellingListIndex())); +} + +static void handleAVRSignalAttr(Sema , Decl *D, +const AttributeList ) { + D->addAttr(::new (S.Context) + AVRSignalAttr(Attr.getLoc(), S.Context, + Attr.getAttributeSpellingListIndex())); +} + static void handleInterruptAttr(Sema , Decl *D, const AttributeList ) { // Dispatch the interrupt attribute based on the current target. switch (S.Context.getTargetInfo().getTriple().getArch()) { @@ -5056,6 +5070,9 @@ 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; @@ -5616,6 +5633,9 @@ case AttributeList::AT_AMDGPUNumVGPR: handleAMDGPUNumVGPRAttr(S, D, Attr); break; + case AttributeList::AT_AVRSignal: +handleAVRSignalAttr(S, D, Attr); +break; case AttributeList::AT_IBAction: handleSimpleAttribute(S, D, Attr); break; Index: lib/CodeGen/TargetInfo.cpp === --- lib/CodeGen/TargetInfo.cpp +++ lib/CodeGen/TargetInfo.cpp @@ -6884,6 +6884,31 @@ } //===--===// +// AVR ABI Implementation. +//===--===// + +namespace { +class AVRTargetCodeGenInfo : public TargetCodeGenInfo { +public: + AVRTargetCodeGenInfo(CodeGenTypes ) +: TargetCodeGenInfo(new DefaultABIInfo(CGT)) { } + + void setTargetAttributes(const Decl *D, llvm::GlobalValue *GV, + CodeGen::CodeGenModule ) const override { +const FunctionDecl *FD = dyn_cast_or_null(D); +if (!FD) return; +llvm::Function *Fn = cast(GV); + +if (FD->getAttr()) + Fn->addFnAttr("interrupt"); + +if (FD->getAttr()) + 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. @@ -8386,6 +8411,9 @@ 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; Index: include/clang/Basic/Attr.td === --- include/clang/Basic/Attr.td +++ include/clang/Basic/Attr.td @@ -255,6 +255,7 @@ list CXXABIs; } def TargetARM : TargetArch<["arm", "thumb", "armeb", "thumbeb"]>; +def
[PATCH] D28451: [AVR] Add support for the 'interrupt' and 'naked' attributes
dylanmckay created this revision. dylanmckay added a reviewer: aaron.ballman. dylanmckay added a subscriber: cfe-commits. This teaches clang how to parse and lower the 'interrupt' and 'naked' attributes. This allows interrupt signal handlers to be written. https://reviews.llvm.org/D28451 Files: include/clang/Basic/Attr.td lib/CodeGen/TargetInfo.cpp lib/Sema/SemaDeclAttr.cpp test/CodeGen/avr/attributes/interrupt.c test/CodeGen/avr/attributes/naked.c Index: test/CodeGen/avr/attributes/naked.c === --- /dev/null +++ test/CodeGen/avr/attributes/naked.c @@ -0,0 +1,6 @@ +// RUN: %clang_cc1 -triple avr-unknown-unknown -emit-llvm %s -o - | FileCheck %s + +// CHECK: define void @foo() #0 +__attribute__((naked)) void foo(void) { } + +// CHECK: attributes #0 = {{{.*naked.*}}} Index: test/CodeGen/avr/attributes/interrupt.c === --- /dev/null +++ test/CodeGen/avr/attributes/interrupt.c @@ -0,0 +1,6 @@ +// RUN: %clang_cc1 -triple avr-unknown-unknown -emit-llvm %s -o - | FileCheck %s + +// CHECK: define void @foo() #0 +__attribute__((interrupt)) void foo(void) { } + +// CHECK: attributes #0 = {{{.*interrupt.*}}} Index: lib/Sema/SemaDeclAttr.cpp === --- lib/Sema/SemaDeclAttr.cpp +++ lib/Sema/SemaDeclAttr.cpp @@ -5042,6 +5042,20 @@ D->addAttr(UsedAttr::CreateImplicit(S.Context)); } +static void handleAVRInterruptAttr(Sema , Decl *D, + const AttributeList ) { + D->addAttr(::new (S.Context) + AVRInterruptAttr(Attr.getLoc(), S.Context, + Attr.getAttributeSpellingListIndex())); +} + +static void handleAVRSignalAttr(Sema , Decl *D, +const AttributeList ) { + D->addAttr(::new (S.Context) + AVRSignalAttr(Attr.getLoc(), S.Context, + Attr.getAttributeSpellingListIndex())); +} + static void handleInterruptAttr(Sema , Decl *D, const AttributeList ) { // Dispatch the interrupt attribute based on the current target. switch (S.Context.getTargetInfo().getTriple().getArch()) { @@ -5056,6 +5070,9 @@ 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; @@ -5616,6 +5633,9 @@ case AttributeList::AT_AMDGPUNumVGPR: handleAMDGPUNumVGPRAttr(S, D, Attr); break; + case AttributeList::AT_AVRSignal: +handleAVRSignalAttr(S, D, Attr); +break; case AttributeList::AT_IBAction: handleSimpleAttribute(S, D, Attr); break; Index: lib/CodeGen/TargetInfo.cpp === --- lib/CodeGen/TargetInfo.cpp +++ lib/CodeGen/TargetInfo.cpp @@ -6884,6 +6884,29 @@ } //===--===// +// AVR ABI Implementation. +//===--===// + +namespace { +class AVRTargetCodeGenInfo : public TargetCodeGenInfo { +public: + AVRTargetCodeGenInfo(CodeGenTypes ) +: TargetCodeGenInfo(new DefaultABIInfo(CGT)) { } + + void setTargetAttributes(const Decl *D, llvm::GlobalValue *GV, + CodeGen::CodeGenModule ) const override { +const FunctionDecl *FD = dyn_cast_or_null(D); +if (!FD) return; +llvm::Function *Fn = cast(GV); + +if (FD->getAttr()) { + Fn->addFnAttr("interrupt"); +} + } +}; +} + +//===--===// // TCE ABI Implementation (see http://tce.cs.tut.fi). Uses mostly the defaults. // Currently subclassed only to implement custom OpenCL C function attribute // handling. @@ -8386,6 +8409,9 @@ 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; Index: include/clang/Basic/Attr.td === --- include/clang/Basic/Attr.td +++ include/clang/Basic/Attr.td @@ -255,6 +255,7 @@ list CXXABIs; } def TargetARM : TargetArch<["arm", "thumb", "armeb", "thumbeb"]>; +def TargetAVR : TargetArch<["avr"]>; def TargetMips : TargetArch<["mips", "mipsel"]>; def TargetMSP430 : TargetArch<["msp430"]>; def TargetX86 : TargetArch<["x86"]>; @@ -477,6 +478,18 @@ let Documentation = [ARMInterruptDocs]; } +def AVRInterrupt : InheritableAttr, TargetSpecificAttr { + let Spellings = [GNU<"interrupt">]; + let Subjects = SubjectList<[Function]>; + let ParseKind = "Interrupt"; + let Documentation = [Undocumented]; +} + +def