[frontend] Add support for disabling the "inline" keyword using 
-fno-inline-functions.

This behaves much like -fno-inline in gcc, but based on a discussion with 
Daniel it was decided that -fno-inline-functions should subsume -fno-inline.
Please speak up if you object.  The -fno-inline flag remains ignored.
Final part of rdar://10972766



git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@152754 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/include/clang/Frontend/CodeGenOptions.h b/include/clang/Frontend/CodeGenOptions.h
index 42b4719..46c0c1e 100644
--- a/include/clang/Frontend/CodeGenOptions.h
+++ b/include/clang/Frontend/CodeGenOptions.h
@@ -78,6 +78,8 @@
   unsigned NoGlobalMerge     : 1; /// Set when -mno-global-merge is enabled.
   unsigned NoImplicitFloat   : 1; /// Set when -mno-implicit-float is enabled.
   unsigned NoInfsFPMath      : 1; /// Assume FP arguments, results not +-Inf.
+  unsigned NoInline          : 1; /// Set when -fno-inline-functions is enabled.
+                                  /// Disables use of inline keyword.
   unsigned NoNaNsFPMath      : 1; /// Assume FP arguments, results not NaN.
   unsigned NoZeroInitializedInBSS : 1; /// -fno-zero-initialized-in-bss
   unsigned ObjCDispatchMethod : 2; /// Method of Objective-C dispatch to use.
@@ -187,6 +189,7 @@
     NoDwarf2CFIAsm = 0;
     NoImplicitFloat = 0;
     NoInfsFPMath = 0;
+    NoInline = 0;
     NoNaNsFPMath = 0;
     NoZeroInitializedInBSS = 0;
     NumRegisterParameters = 0;
diff --git a/lib/CodeGen/CodeGenFunction.cpp b/lib/CodeGen/CodeGenFunction.cpp
index b80cedd..06e90b6 100644
--- a/lib/CodeGen/CodeGenFunction.cpp
+++ b/lib/CodeGen/CodeGenFunction.cpp
@@ -266,13 +266,14 @@
 
   // Pass inline keyword to optimizer if it appears explicitly on any
   // declaration.
-  if (const FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>(D))
-    for (FunctionDecl::redecl_iterator RI = FD->redecls_begin(),
-           RE = FD->redecls_end(); RI != RE; ++RI)
-      if (RI->isInlineSpecified()) {
-        Fn->addFnAttr(llvm::Attribute::InlineHint);
-        break;
-      }
+  if (!CGM.getCodeGenOpts().NoInline) 
+    if (const FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>(D))
+      for (FunctionDecl::redecl_iterator RI = FD->redecls_begin(),
+             RE = FD->redecls_end(); RI != RE; ++RI)
+        if (RI->isInlineSpecified()) {
+          Fn->addFnAttr(llvm::Attribute::InlineHint);
+          break;
+        }
 
   if (getContext().getLangOpts().OpenCL) {
     // Add metadata for a kernel function.
diff --git a/lib/Frontend/CompilerInvocation.cpp b/lib/Frontend/CompilerInvocation.cpp
index 13a9897..ffc1276 100644
--- a/lib/Frontend/CompilerInvocation.cpp
+++ b/lib/Frontend/CompilerInvocation.cpp
@@ -1165,8 +1165,9 @@
   Opts.Inlining = (Opts.OptimizationLevel > 1) ? CodeGenOptions::NormalInlining
     : CodeGenOptions::OnlyAlwaysInlining;
   // -fno-inline-functions overrides OptimizationLevel > 1.
-  Opts.Inlining = Args.hasArg(OPT_fno_inline_functions) ? 
-    CodeGenOptions::OnlyAlwaysInlining : Opts.Inlining;
+  Opts.NoInline = Args.hasArg(OPT_fno_inline_functions);
+  Opts.Inlining = Opts.NoInline ? CodeGenOptions::OnlyAlwaysInlining :
+    Opts.Inlining;
 
   Opts.DebugInfo = Args.hasArg(OPT_g);
   Opts.LimitDebugInfo = !Args.hasArg(OPT_fno_limit_debug_info)
diff --git a/test/CodeGen/noinline.c b/test/CodeGen/noinline.c
index 91cd5d4..4576881 100644
--- a/test/CodeGen/noinline.c
+++ b/test/CodeGen/noinline.c
@@ -3,11 +3,12 @@
 
 // RUN: %clang_cc1 -O3 -fno-inline-functions -emit-llvm %s -o - | FileCheck -check-prefix=NOINLINE %s
 
-int dont_inline_me(int a, int b) { return(a+b); }
+inline int dont_inline_me(int a, int b) { return(a+b); }
 
 volatile int *pa = (int*) 0x1000;
 void foo() {
 // NOINLINE: @foo
 // NOINLINE: dont_inline_me
+// NOINLINE-NOT: inlinehint
     pa[0] = dont_inline_me(pa[1],pa[2]);	
 }