aboutsummaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/CodeGen/CodeGenModule.cpp4
-rw-r--r--lib/Parse/ParseDecl.cpp11
-rw-r--r--lib/Sema/SemaDeclAttr.cpp10
3 files changed, 20 insertions, 5 deletions
diff --git a/lib/CodeGen/CodeGenModule.cpp b/lib/CodeGen/CodeGenModule.cpp
index e64a20403c..c72b8665f3 100644
--- a/lib/CodeGen/CodeGenModule.cpp
+++ b/lib/CodeGen/CodeGenModule.cpp
@@ -518,7 +518,7 @@ void CodeGenModule::SetLLVMFunctionAttributesForDefinition(const Decl *D,
F->addFnAttr(llvm::Attribute::NoInline);
// (noinline wins over always_inline, and we can't specify both in IR)
- if (D->hasAttr<AlwaysInlineAttr>() &&
+ if ((D->hasAttr<AlwaysInlineAttr>() || D->hasAttr<ForceInlineAttr>()) &&
!F->hasFnAttr(llvm::Attribute::NoInline))
F->addFnAttr(llvm::Attribute::AlwaysInline);
@@ -935,7 +935,7 @@ CodeGenModule::shouldEmitFunction(const FunctionDecl *F) {
if (getFunctionLinkage(F) != llvm::Function::AvailableExternallyLinkage)
return true;
if (CodeGenOpts.OptimizationLevel == 0 &&
- !F->hasAttr<AlwaysInlineAttr>())
+ !F->hasAttr<AlwaysInlineAttr>() && !F->hasAttr<ForceInlineAttr>())
return false;
// PR9614. Avoid cases where the source code is lying to us. An available
// externally function should have an equivalent function somewhere else,
diff --git a/lib/Parse/ParseDecl.cpp b/lib/Parse/ParseDecl.cpp
index f48f9e8c68..ee394f885b 100644
--- a/lib/Parse/ParseDecl.cpp
+++ b/lib/Parse/ParseDecl.cpp
@@ -2251,9 +2251,14 @@ void Parser::ParseDeclarationSpecifiers(DeclSpec &DS,
continue;
// Microsoft single token adornments.
- case tok::kw___forceinline:
- // FIXME: Add handling here!
- break;
+ case tok::kw___forceinline: {
+ isInvalid = DS.SetFunctionSpecInline(Loc, PrevSpec, DiagID);
+ IdentifierInfo *AttrName = Tok.getIdentifierInfo();
+ SourceLocation AttrNameLoc = ConsumeToken();
+ DS.getAttributes().addNew(AttrName, AttrNameLoc, 0, AttrNameLoc, 0,
+ SourceLocation(), 0, 0);
+ continue;
+ }
case tok::kw___ptr64:
case tok::kw___ptr32:
diff --git a/lib/Sema/SemaDeclAttr.cpp b/lib/Sema/SemaDeclAttr.cpp
index 516f697652..b8df752b38 100644
--- a/lib/Sema/SemaDeclAttr.cpp
+++ b/lib/Sema/SemaDeclAttr.cpp
@@ -3888,6 +3888,13 @@ static void handlePortabilityAttr(Sema &S, Decl *D, const AttributeList &Attr) {
S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << Attr.getName();
}
+static void handleForceInlineAttr(Sema &S, Decl *D, const AttributeList &Attr) {
+ if (S.LangOpts.MicrosoftExt)
+ D->addAttr(::new (S.Context) ForceInlineAttr(Attr.getRange(), S.Context));
+ else
+ S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << Attr.getName();
+}
+
//===----------------------------------------------------------------------===//
// Top Level Sema Entry Points
//===----------------------------------------------------------------------===//
@@ -4082,6 +4089,9 @@ static void ProcessInheritableDeclAttr(Sema &S, Scope *scope, Decl *D,
case AttributeList::AT_ptr64:
handlePortabilityAttr(S, D, Attr);
break;
+ case AttributeList::AT_forceinline:
+ handleForceInlineAttr(S, D, Attr);
+ break;
// Thread safety attributes:
case AttributeList::AT_guarded_var: