diff options
author | Tim Northover <tnorthover@apple.com> | 2013-10-01 14:34:25 +0000 |
---|---|---|
committer | Tim Northover <tnorthover@apple.com> | 2013-10-01 14:34:25 +0000 |
commit | a484bc00ff592bd2efb9c37c70222994aa6f9508 (patch) | |
tree | 31934e502d5bddc5f1558ed71e16711f08845ce1 /clang/lib/Sema/TargetAttributesSema.cpp | |
parent | 6a6b63b464e55ff2bd124fca468a8a800b6cd8cd (diff) | |
download | bcm5719-llvm-a484bc00ff592bd2efb9c37c70222994aa6f9508.tar.gz bcm5719-llvm-a484bc00ff592bd2efb9c37c70222994aa6f9508.zip |
Implement ARM GNU-style interrupt attribute
This attribute allows users to use a modified C or C++ function as an ARM
exception-handling function and, with care, to successfully return control to
user-space after the issue has been dealt with.
rdar://problem/14207019
llvm-svn: 191769
Diffstat (limited to 'clang/lib/Sema/TargetAttributesSema.cpp')
-rw-r--r-- | clang/lib/Sema/TargetAttributesSema.cpp | 47 |
1 files changed, 47 insertions, 0 deletions
diff --git a/clang/lib/Sema/TargetAttributesSema.cpp b/clang/lib/Sema/TargetAttributesSema.cpp index 7db0b241fa5..45067dee9b8 100644 --- a/clang/lib/Sema/TargetAttributesSema.cpp +++ b/clang/lib/Sema/TargetAttributesSema.cpp @@ -26,6 +26,50 @@ bool TargetAttributesSema::ProcessDeclAttribute(Scope *scope, Decl *D, return false; } +static void HandleARMInterruptAttr(Decl *d, + const AttributeList &Attr, Sema &S) { + // Check the attribute arguments. + if (Attr.getNumArgs() > 1) { + S.Diag(Attr.getLoc(), diag::err_attribute_too_many_arguments) + << 1; + return; + } + + StringRef Str; + SourceLocation ArgLoc; + + if (Attr.getNumArgs() == 0) + Str = ""; + else if (!S.checkStringLiteralArgumentAttr(Attr, 0, Str, &ArgLoc)) + return; + + ARMInterruptAttr::InterruptType Kind; + if (!ARMInterruptAttr::ConvertStrToInterruptType(Str, Kind)) { + S.Diag(Attr.getLoc(), diag::warn_attribute_type_not_supported) + << Attr.getName() << Str << ArgLoc; + return; + } + + unsigned Index = Attr.getAttributeSpellingListIndex(); + d->addAttr(::new (S.Context) + ARMInterruptAttr(Attr.getLoc(), S.Context, Kind, Index)); +} + +namespace { + class ARMAttributesSema : public TargetAttributesSema { + public: + ARMAttributesSema() { } + bool ProcessDeclAttribute(Scope *scope, Decl *D, + const AttributeList &Attr, Sema &S) const { + if (Attr.getName()->getName() == "interrupt") { + HandleARMInterruptAttr(D, Attr, S); + return true; + } + return false; + } + }; +} + static void HandleMSP430InterruptAttr(Decl *d, const AttributeList &Attr, Sema &S) { // Check the attribute arguments. @@ -292,6 +336,9 @@ const TargetAttributesSema &Sema::getTargetAttributesSema() const { const llvm::Triple &Triple(Context.getTargetInfo().getTriple()); switch (Triple.getArch()) { + case llvm::Triple::arm: + case llvm::Triple::thumb: + return *(TheTargetAttributesSema = new ARMAttributesSema); case llvm::Triple::msp430: return *(TheTargetAttributesSema = new MSP430AttributesSema); case llvm::Triple::x86: |