aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCharles Davis <cdavis@mines.edu>2010-02-10 23:06:52 +0000
committerCharles Davis <cdavis@mines.edu>2010-02-10 23:06:52 +0000
commit5a0164d6ab843ca61437ec59a504365cb1c98f43 (patch)
tree30148221767946041f371262ad561cf665051a01
parentc0f3df3245fa2737b459e198273762a27b76f75a (diff)
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
-rw-r--r--include/clang/AST/Attr.h5
-rw-r--r--lib/AST/AttrImpl.cpp1
-rw-r--r--lib/Sema/TargetAttributesSema.cpp42
-rw-r--r--test/Sema/x86-attr-force-align-arg-pointer.c18
4 files changed, 65 insertions, 1 deletions
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<ValueDecl>(D);
+ if(VD->getType()->isFunctionPointerType())
+ return;
+ // Attribute can only be applied to function types.
+ if(!isa<FunctionDecl>(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)();
+