From: Chris Lattner Date: Tue, 14 Apr 2009 17:02:11 +0000 (+0000) Subject: implement some sema for gnuc_inline attribute. Reject always_inline and no_inline... X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=c51974328b3a378c3c40b1fa527ecb928ed2bfda;p=clang implement some sema for gnuc_inline attribute. Reject always_inline and no_inline on objc methods. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@69051 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/Basic/DiagnosticSemaKinds.td b/include/clang/Basic/DiagnosticSemaKinds.td index c629a82a2c..a29ffce41e 100644 --- a/include/clang/Basic/DiagnosticSemaKinds.td +++ b/include/clang/Basic/DiagnosticSemaKinds.td @@ -398,6 +398,11 @@ def warn_attribute_weak_import_invalid_on_definition : Warning< def warn_attribute_wrong_decl_type : Warning< "'%0' attribute only applies to %select{function|union|" "variable and function|function or method}1 types">; +def warn_gnuc_inline_attribute_requires_inline : Warning< + "'gnuc_inline' attribute requires function to be marked 'inline'," + " attribute ignored">; +def warn_gnuc_inline_attribute_extern_inline : Warning< + "'gnuc_inline' attribute is overridden by 'extern inline', attribute ignored">; def warn_attribute_ignored_for_field_of_type : Warning< "%0 attribute ignored for field of type %1">; diff --git a/lib/Sema/SemaDeclAttr.cpp b/lib/Sema/SemaDeclAttr.cpp index 5b611e1d18..cafa67fde7 100644 --- a/lib/Sema/SemaDeclAttr.cpp +++ b/lib/Sema/SemaDeclAttr.cpp @@ -391,7 +391,7 @@ static void HandleAlwaysInlineAttr(Decl *d, const AttributeList &Attr, return; } - if (!isFunctionOrMethod(d)) { + if (!isa(d)) { S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) << "always_inline" << 0 /*function*/; return; @@ -485,8 +485,7 @@ static void HandleConstructorAttr(Decl *d, const AttributeList &Attr, Sema &S) { priority = Idx.getZExtValue(); } - FunctionDecl *Fn = dyn_cast(d); - if (!Fn) { + if (!isa(d)) { S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) << "constructor" << 0 /*function*/; return; @@ -1447,7 +1446,7 @@ static void HandleNoinlineAttr(Decl *d, const AttributeList &Attr, Sema &S) { return; } - if (!isFunctionOrMethod(d)) { + if (!isa(d)) { S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) << "noinline" << 0 /*function*/; return; @@ -1463,12 +1462,23 @@ static void HandleGNUCInlineAttr(Decl *d, const AttributeList &Attr, Sema &S) { return; } - if (!isFunctionOrMethod(d)) { + FunctionDecl *Fn = dyn_cast(d); + if (Fn == 0) { S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) << "gnuc_inline" << 0 /*function*/; return; } + if (!Fn->isInline()) { + S.Diag(Attr.getLoc(), diag::warn_gnuc_inline_attribute_requires_inline); + return; + } + + if (Fn->getStorageClass() == FunctionDecl::Extern) { + S.Diag(Attr.getLoc(), diag::warn_gnuc_inline_attribute_extern_inline); + return; + } + d->addAttr(::new (S.Context) GNUCInlineAttr()); } diff --git a/test/Sema/function.c b/test/Sema/function.c index e604d0e1ea..3a0352d753 100644 --- a/test/Sema/function.c +++ b/test/Sema/function.c @@ -61,3 +61,12 @@ void f1static() { struct incomplete_test a(void) {} // expected-error{{incomplete result type 'struct incomplete_test' in function definition}} \ // expected-note{{forward declaration of 'struct incomplete_test'}} + + +extern __inline +__attribute__((__gnuc_inline__)) // expected-warning{{'gnuc_inline' attribute is overridden by 'extern inline', attribute ignored}} expected-warning{{extension used}} +void gnu_inline1() {} + +void +__attribute__((__gnuc_inline__)) // expected-warning {{'gnuc_inline' attribute requires function to be marked 'inline', attribute ignored}} expected-warning{{extension used}} +gnu_inline2() {}