diff options
Diffstat (limited to 'clang/lib')
-rw-r--r-- | clang/lib/Sema/SemaDeclAttr.cpp | 20 |
1 files changed, 15 insertions, 5 deletions
diff --git a/clang/lib/Sema/SemaDeclAttr.cpp b/clang/lib/Sema/SemaDeclAttr.cpp index 5b611e1d18a..cafa67fde75 100644 --- a/clang/lib/Sema/SemaDeclAttr.cpp +++ b/clang/lib/Sema/SemaDeclAttr.cpp @@ -391,7 +391,7 @@ static void HandleAlwaysInlineAttr(Decl *d, const AttributeList &Attr, return; } - if (!isFunctionOrMethod(d)) { + if (!isa<FunctionDecl>(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<FunctionDecl>(d); - if (!Fn) { + if (!isa<FunctionDecl>(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<FunctionDecl>(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<FunctionDecl>(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()); } |