Index: test/Parser/skip-function-bodies.mm
===================================================================
--- test/Parser/skip-function-bodies.mm	(revision 164117)
+++ test/Parser/skip-function-bodies.mm	(working copy)
@@ -30,7 +30,7 @@
 // CHECK: skip-function-bodies.mm:3:7: ClassDecl=A:3:7 (Definition) Extent=[3:1 - 14:2]
 // CHECK: skip-function-bodies.mm:4:9: ClassDecl=B:4:9 (Definition) Extent=[4:3 - 4:13]
 // CHECK: skip-function-bodies.mm:6:1: CXXAccessSpecifier=:6:1 (Definition) Extent=[6:1 - 6:8]
-// CHECK: skip-function-bodies.mm:7:3: CXXConstructor=A:7:3 Extent=[7:3 - 7:6]
+// CHECK: skip-function-bodies.mm:7:3: CXXConstructor=A:7:3 (Definition) Extent=[7:3 - 7:6]
 // CHECK-NOT: skip-function-bodies.mm:8:12: StructDecl=C:8:12 (Definition) Extent=[8:5 - 10:6]
 // CHECK-NOT: skip-function-bodies.mm:9:12: CXXMethod=d:9:12 (Definition) Extent=[9:7 - 9:18]
 // CHECK: skip-function-bodies.mm:13:13: TypedefDecl=E:13:13 (Definition) Extent=[13:3 - 13:14]
@@ -41,5 +41,5 @@
 // CHECK: skip-function-bodies.mm:20:10: ObjCInstanceMethodDecl=G:20:10 Extent=[20:1 - 20:13]
 // CHECK-NOT: skip-function-bodies.mm:21:13: TypedefDecl=H:21:13 (Definition) Extent=[21:3 - 21:14]
 // CHECK-NOT: skip-function-bodies.mm:21:11: TypeRef=class A:3:7 Extent=[21:11 - 21:12]
-// CHECK: skip-function-bodies.mm:26:6: FunctionDecl=J:26:6 Extent=[26:1 - 26:9]
+// CHECK: skip-function-bodies.mm:26:6: FunctionDecl=J:26:6 (Definition) Extent=[26:1 - 26:9]
 // CHECK-NOT: skip-function-bodies.mm:27:9: ClassDecl=K:27:9 (Definition) Extent=[27:3 - 27:13]
Index: include/clang/Sema/Sema.h
===================================================================
--- include/clang/Sema/Sema.h	(revision 164117)
+++ include/clang/Sema/Sema.h	(working copy)
@@ -1332,9 +1332,11 @@
   }
 
   void computeNRVO(Stmt *Body, sema::FunctionScopeInfo *Scope);
-  Decl *ActOnFinishFunctionBody(Decl *Decl, Stmt *Body);
-  Decl *ActOnFinishFunctionBody(Decl *Decl, Stmt *Body, bool IsInstantiation);
 
+  Decl *ActOnFinishFunctionBody(Decl *Decl, Stmt *Body,
+                                bool IsInstantiation = false,
+                                bool IsBodySkipped = false);
+
   /// ActOnFinishDelayedAttribute - Invoked when we have finished parsing an
   /// attribute for which parsing is delayed.
   void ActOnFinishDelayedAttribute(Scope *S, Decl *D, ParsedAttributes &Attrs);
Index: include/clang/AST/Decl.h
===================================================================
--- include/clang/AST/Decl.h	(revision 164117)
+++ include/clang/AST/Decl.h	(working copy)
@@ -1478,6 +1478,7 @@
   bool HasImplicitReturnZero : 1;
   bool IsLateTemplateParsed : 1;
   bool IsConstexpr : 1;
+  bool IsBodySkipped : 1;
 
   /// \brief End part of this FunctionDecl's source range.
   ///
@@ -1562,8 +1563,8 @@
       HasWrittenPrototype(true), IsDeleted(false), IsTrivial(false),
       IsDefaulted(false), IsExplicitlyDefaulted(false),
       HasImplicitReturnZero(false), IsLateTemplateParsed(false),
-      IsConstexpr(isConstexprSpecified), EndRangeLoc(NameInfo.getEndLoc()),
-      TemplateOrSpecialization(),
+      IsConstexpr(isConstexprSpecified), IsBodySkipped(false),
+      EndRangeLoc(NameInfo.getEndLoc()), TemplateOrSpecialization(),
       DNLoc(NameInfo.getInfo()) {}
 
   typedef Redeclarable<FunctionDecl> redeclarable_base;
@@ -1662,6 +1663,12 @@
     return getBody(Definition);
   }
 
+  /// isBodySkipped - Returns true if the body existed but was skipped
+  /// due to translation unit options.
+  bool isBodySkipped() const {
+    return IsBodySkipped;
+  }
+
   /// isThisDeclarationADefinition - Returns whether this specific
   /// declaration of the function is also a definition. This does not
   /// determine whether the function has been defined (e.g., in a
@@ -1682,6 +1689,10 @@
   void setBody(Stmt *B);
   void setLazyBody(uint64_t Offset) { Body = Offset; }
 
+  void setBodySkipped(bool BS) {
+    IsBodySkipped = BS;
+  }
+
   /// Whether this function is variadic.
   bool isVariadic() const;
 
Index: tools/libclang/CIndex.cpp
===================================================================
--- tools/libclang/CIndex.cpp	(revision 164117)
+++ tools/libclang/CIndex.cpp	(working copy)
@@ -4380,7 +4380,10 @@
   case Decl::CXXDestructor:
   case Decl::CXXConversion: {
     const FunctionDecl *Def = 0;
-    if (cast<FunctionDecl>(D)->getBody(Def))
+    if (cast<FunctionDecl>(D)->isBodySkipped()) {
+      // The body actually exists but isn't available.
+      return C;
+    } else if (cast<FunctionDecl>(D)->getBody(Def))
       return MakeCXCursor(const_cast<FunctionDecl *>(Def), TU);
     return clang_getNullCursor();
   }
Index: lib/Sema/SemaDecl.cpp
===================================================================
--- lib/Sema/SemaDecl.cpp	(revision 164117)
+++ lib/Sema/SemaDecl.cpp	(working copy)
@@ -7777,12 +7777,9 @@
     const_cast<VarDecl*>(NRVOCandidate)->setNRVOVariable(true);
 }
 
-Decl *Sema::ActOnFinishFunctionBody(Decl *D, Stmt *BodyArg) {
-  return ActOnFinishFunctionBody(D, BodyArg, false);
-}
-
 Decl *Sema::ActOnFinishFunctionBody(Decl *dcl, Stmt *Body,
-                                    bool IsInstantiation) {
+                                    bool IsInstantiation,
+                                    bool IsBodySkipped) {
   FunctionDecl *FD = 0;
   FunctionTemplateDecl *FunTmpl = dyn_cast_or_null<FunctionTemplateDecl>(dcl);
   if (FunTmpl)
@@ -7794,6 +7791,7 @@
   sema::AnalysisBasedWarnings::Policy *ActivePolicy = 0;
 
   if (FD) {
+    FD->setBodySkipped(IsBodySkipped);
     FD->setBody(Body);
 
     // If the function implicitly returns zero (like 'main') or is naked,
Index: lib/Parse/ParseStmt.cpp
===================================================================
--- lib/Parse/ParseStmt.cpp	(revision 164117)
+++ lib/Parse/ParseStmt.cpp	(working copy)
@@ -1919,7 +1919,9 @@
 
   if (SkipFunctionBodies && trySkippingFunctionBody()) {
     BodyScope.Exit();
-    return Actions.ActOnFinishFunctionBody(Decl, 0);
+    return Actions.ActOnFinishFunctionBody(Decl, 0,
+                                           /*IsInstantiation =*/false,
+                                           /*IsBodySkipped =*/true);
   }
 
   PrettyDeclStackTraceEntry CrashInfo(Actions, Decl, LBraceLoc,
@@ -1961,7 +1963,9 @@
 
   if (SkipFunctionBodies && trySkippingFunctionBody()) {
     BodyScope.Exit();
-    return Actions.ActOnFinishFunctionBody(Decl, 0);
+    return Actions.ActOnFinishFunctionBody(Decl, 0,
+                                           /*IsInstantiation =*/false,
+                                           /*IsBodySkipped =*/true);
   }
 
   SourceLocation LBraceLoc = Tok.getLocation();
