From: Anders Carlsson Date: Thu, 19 Feb 2009 19:16:48 +0000 (+0000) Subject: Add sema support for the noinline attribute. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=5bab788d40026ad6e932a3cd9b86bc13f8a27661;p=clang Add sema support for the noinline attribute. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@65055 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/AST/Attr.h b/include/clang/AST/Attr.h index b2c5c23a4f..e814c5c719 100644 --- a/include/clang/AST/Attr.h +++ b/include/clang/AST/Attr.h @@ -58,7 +58,8 @@ public: Const, Pure, Cleanup, - Nodebug + Nodebug, + Noinline }; private: @@ -499,7 +500,7 @@ public: // Implement isa/cast/dyncast/etc. static bool classof(const Attr *A) { return A->getKind() == Nodebug; } - static bool classof(const DeprecatedAttr *A) { return true; } + static bool classof(const NodebugAttr *A) { return true; } }; class WarnUnusedResultAttr : public Attr { @@ -510,7 +511,17 @@ public: static bool classof(const Attr *A) { return A->getKind() == WarnUnusedResult;} static bool classof(const WarnUnusedResultAttr *A) { return true; } }; - + +class NoinlineAttr : public Attr { +public: + NoinlineAttr() : Attr(Noinline) {} + + // Implement isa/cast/dyncast/etc. + + static bool classof(const Attr *A) { return A->getKind() == Noinline; } + static bool classof(const NoinlineAttr *A) { return true; } +}; + } // end namespace clang #endif diff --git a/lib/Sema/SemaDeclAttr.cpp b/lib/Sema/SemaDeclAttr.cpp index 614e53a751..2ceea33d07 100644 --- a/lib/Sema/SemaDeclAttr.cpp +++ b/lib/Sema/SemaDeclAttr.cpp @@ -395,6 +395,12 @@ static void HandleAlwaysInlineAttr(Decl *d, const AttributeList &Attr, S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0; return; } + + if (!isFunctionOrMethod(d)) { + S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) + << "always_inline" << 0 /*function*/; + return; + } d->addAttr(new AlwaysInlineAttr()); } @@ -1343,7 +1349,7 @@ static void HandleNodebugAttr(Decl *d, const AttributeList &Attr, Sema &S) { return; } - if (!isa(d)) { + if (!isFunctionOrMethod(d)) { S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) << "nodebug" << 0 /*function*/; return; @@ -1352,6 +1358,22 @@ static void HandleNodebugAttr(Decl *d, const AttributeList &Attr, Sema &S) { d->addAttr(new NodebugAttr()); } +static void HandleNoinlineAttr(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 (!isFunctionOrMethod(d)) { + S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) + << "noinline" << 0 /*function*/; + return; + } + + d->addAttr(new NoinlineAttr()); +} + //===----------------------------------------------------------------------===// // Top Level Sema Entry Points //===----------------------------------------------------------------------===// @@ -1410,6 +1432,7 @@ static void ProcessDeclAttribute(Decl *D, const AttributeList &Attr, Sema &S) { case AttributeList::AT_pure: HandlePureAttr (D, Attr, S); break; case AttributeList::AT_cleanup: HandleCleanupAttr (D, Attr, S); break; case AttributeList::AT_nodebug: HandleNodebugAttr (D, Attr, S); break; + case AttributeList::AT_noinline: HandleNoinlineAttr (D, Attr, S); break; case AttributeList::IgnoredAttribute: // Just ignore break; diff --git a/test/Sema/attr-noinline.c b/test/Sema/attr-noinline.c new file mode 100644 index 0000000000..2d1c0f00d4 --- /dev/null +++ b/test/Sema/attr-noinline.c @@ -0,0 +1,8 @@ +// RUN: clang %s -verify -fsyntax-only + +int a __attribute__((noinline)); // expected-warning {{'noinline' attribute only applies to function types}} + +void t1() __attribute__((noinline)); + +void t2() __attribute__((noinline(2))); // expected-error {{attribute requires 0 argument(s)}} +