Index: include/clang/Basic/Attr.td =================================================================== --- include/clang/Basic/Attr.td +++ include/clang/Basic/Attr.td @@ -866,7 +866,7 @@ } def GNUInline : InheritableAttr { - let Spellings = [GCC<"gnu_inline">]; + let Spellings = [GCC<"gnu_inline">, Declspec<"inline">]; let Subjects = SubjectList<[Function]>; let Documentation = [Undocumented]; } Index: lib/Parse/ParseDecl.cpp =================================================================== --- lib/Parse/ParseDecl.cpp +++ lib/Parse/ParseDecl.cpp @@ -639,7 +639,10 @@ // else is a malformed declspec. bool IsString = Tok.getKind() == tok::string_literal; if (!IsString && Tok.getKind() != tok::identifier && - Tok.getKind() != tok::kw_restrict) { + Tok.getKind() != tok::kw_restrict && + (Tok.getKind() != tok::kw_inline || + (Tok.getKind() == tok::kw_inline && + getLangOpts().CPlusPlus) ) ){ Diag(Tok, diag::err_ms_declspec_type); T.skipToEnd(); return; Index: lib/Sema/SemaDeclAttr.cpp =================================================================== --- lib/Sema/SemaDeclAttr.cpp +++ lib/Sema/SemaDeclAttr.cpp @@ -4377,7 +4377,7 @@ static void handleGNUInlineAttr(Sema &S, Decl *D, const AttributeList &Attr) { FunctionDecl *Fn = cast(D); - if (!Fn->isInlineSpecified()) { + if (!Fn->isInlineSpecified() && !Attr.isDeclspecAttribute()) { S.Diag(Attr.getLoc(), diag::warn_gnu_inline_attribute_requires_inline); return; } Index: test/Sema/declspec-inline.c =================================================================== --- test/Sema/declspec-inline.c +++ test/Sema/declspec-inline.c @@ -0,0 +1,18 @@ +// RUN: %clang_cc1 -verify -fms-compatibility %s +// expected-no-diagnostics + +static int __declspec(inline) foo(int i) { + int k; + int a[10000]; + for (k=0; k<=i; k++) + { + a[k] = a[k]*k; + } + return a[k]; +} + +int main() +{ + int i=20; + return foo(2000); +}