From: Charles Davis Date: Wed, 10 Feb 2010 23:06:52 +0000 (+0000) Subject: Add support for the force_align_arg_pointer attribute. This is an x86-specific X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=5a0164d6ab843ca61437ec59a504365cb1c98f43;p=clang Add support for the force_align_arg_pointer attribute. This is an x86-specific attribute, so it uses Anton's new target-specific attribute support. It's supposed to ensure that the stack is 16-byte aligned, but since necessary support is lacking from LLVM, this is a no-op for now. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@95820 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/AST/Attr.h b/include/clang/AST/Attr.h index 03ab0f0702..0125985c1c 100644 --- a/include/clang/AST/Attr.h +++ b/include/clang/AST/Attr.h @@ -96,7 +96,8 @@ public: FIRST_TARGET_ATTRIBUTE, DLLExport, DLLImport, - MSP430Interrupt + MSP430Interrupt, + X86ForceAlignArgPointer }; private: @@ -570,6 +571,8 @@ public: static bool classof(const MSP430InterruptAttr *A) { return true; } }; +DEF_SIMPLE_ATTR(X86ForceAlignArgPointer); + #undef DEF_SIMPLE_ATTR } // end namespace clang diff --git a/lib/AST/AttrImpl.cpp b/lib/AST/AttrImpl.cpp index 02c70b6511..42c099d66c 100644 --- a/lib/AST/AttrImpl.cpp +++ b/lib/AST/AttrImpl.cpp @@ -55,6 +55,7 @@ DEF_SIMPLE_ATTR_CLONE(Hiding) DEF_SIMPLE_ATTR_CLONE(Override) DEF_SIMPLE_ATTR_CLONE(DLLImport) DEF_SIMPLE_ATTR_CLONE(DLLExport) +DEF_SIMPLE_ATTR_CLONE(X86ForceAlignArgPointer) Attr* PragmaPackAttr::clone(ASTContext &C) const { return ::new (C) PragmaPackAttr(Alignment); diff --git a/lib/Sema/TargetAttributesSema.cpp b/lib/Sema/TargetAttributesSema.cpp index 7c19bf6e4f..ab54949c99 100644 --- a/lib/Sema/TargetAttributesSema.cpp +++ b/lib/Sema/TargetAttributesSema.cpp @@ -70,6 +70,46 @@ namespace { }; } +static void HandleX86ForceAlignArgPointerAttr(Decl *D, + const AttributeList& Attr, + Sema &S) { + // Check the attribute arguments. + if (Attr.getNumArgs() != 0) { + S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; + return; + } + + // If we try to apply it to a function pointer, don't warn, but don't + // do anything, either. It doesn't matter anyway, because there's nothing + // special about calling a force_align_arg_pointer function. + ValueDecl* VD = dyn_cast(D); + if(VD->getType()->isFunctionPointerType()) + return; + // Attribute can only be applied to function types. + if(!isa(D)) { + S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) + << Attr.getName() << /* function */0; + return; + } + + D->addAttr(::new (S.Context) X86ForceAlignArgPointerAttr()); +} + +namespace { + class X86AttributesSema : public TargetAttributesSema { + public: + X86AttributesSema() { } + bool ProcessDeclAttribute(Scope *scope, Decl *D, + const AttributeList &Attr, Sema &S) const { + if (Attr.getName()->getName() == "force_align_arg_pointer") { + HandleX86ForceAlignArgPointerAttr(D, Attr, S); + return true; + } + return false; + } + }; +} + const TargetAttributesSema &Sema::getTargetAttributesSema() const { if (TheTargetAttributesSema) return *TheTargetAttributesSema; @@ -81,6 +121,8 @@ const TargetAttributesSema &Sema::getTargetAttributesSema() const { case llvm::Triple::msp430: return *(TheTargetAttributesSema = new MSP430AttributesSema); + case llvm::Triple::x86: + return *(TheTargetAttributesSema = new X86AttributesSema); } } diff --git a/test/Sema/x86-attr-force-align-arg-pointer.c b/test/Sema/x86-attr-force-align-arg-pointer.c new file mode 100644 index 0000000000..1470544a69 --- /dev/null +++ b/test/Sema/x86-attr-force-align-arg-pointer.c @@ -0,0 +1,18 @@ +// RUN: %clang_cc1 -triple i386-apple-darwin10 -fsyntax-only -verify %s + +int a __attribute__((force_align_arg_pointer)); // expected-warning{{attribute only applies to function types}} + +// It doesn't matter where the attribute is located. +void b(void) __attribute__((force_align_arg_pointer)); +void __attribute__((force_align_arg_pointer)) c(void); + +// Functions only have to be declared force_align_arg_pointer once. +void b(void) {} + +// It doesn't matter which declaration has the attribute. +void d(void); +void __attribute__((force_align_arg_pointer)) d(void) {} + +// Attribute is ignored on function pointer types. +void (__attribute__((force_align_arg_pointer)) *p)(); +