[PATCH] D28451: [AVR] Add support for the 'interrupt' and 'naked' attributes

2017-02-07 Thread Dylan McKay via Phabricator via cfe-commits
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

2017-02-07 Thread Aaron Ballman via Phabricator via cfe-commits
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

2017-02-06 Thread Dylan McKay via Phabricator via cfe-commits
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

2017-02-06 Thread Dylan McKay via Phabricator via cfe-commits
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

2017-02-05 Thread Dylan McKay via Phabricator via cfe-commits
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

2017-02-05 Thread Dylan McKay via Phabricator via cfe-commits
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

2017-02-05 Thread Dylan McKay via Phabricator via cfe-commits
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

2017-02-05 Thread Aaron Ballman via Phabricator via cfe-commits
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

2017-02-05 Thread Dylan McKay via Phabricator via cfe-commits
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

2017-02-05 Thread Aaron Ballman via Phabricator via cfe-commits
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

2017-02-03 Thread Dylan McKay via Phabricator via cfe-commits
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

2017-01-23 Thread Aaron Ballman via Phabricator via cfe-commits
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

2017-01-20 Thread Malcolm Parsons via Phabricator via cfe-commits
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

2017-01-19 Thread Dylan McKay via Phabricator via cfe-commits
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

2017-01-19 Thread Dylan McKay via Phabricator via cfe-commits
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

2017-01-19 Thread Dylan McKay via Phabricator via cfe-commits
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

2017-01-19 Thread Dylan McKay via Phabricator via cfe-commits
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

2017-01-12 Thread Aaron Ballman via Phabricator via cfe-commits
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

2017-01-10 Thread Dylan McKay via Phabricator via cfe-commits
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

2017-01-10 Thread Dylan McKay via Phabricator via cfe-commits
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

2017-01-10 Thread Aaron Ballman via Phabricator via cfe-commits
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

2017-01-07 Thread Dylan McKay via Phabricator via cfe-commits
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

2017-01-07 Thread Dylan McKay via Phabricator via cfe-commits
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