Index: test/CodeGenCXX/debug-info-gline-tables-only.cpp
===================================================================
--- test/CodeGenCXX/debug-info-gline-tables-only.cpp	(revision 0)
+++ test/CodeGenCXX/debug-info-gline-tables-only.cpp	(revision 0)
@@ -0,0 +1,21 @@
+// RUN: %clang_cc1 %s -O0 -gline-tables-only -S -emit-llvm -o - | FileCheck %s
+// Checks that clang with "-gline-tables-only" doesn't emit debug info
+// for variables and types.
+
+// CHECK-NOT: DW_TAG_namespace
+namespace NS {
+// CHECK-NOT: DW_TAG_class_type
+// CHECK-NOT: DW_TAG_friend
+class C { friend class D; };
+class D {};
+// CHECK-NOT: DW_TAG_inheritance
+class E : public C {
+  // CHECK-NOT: DW_TAG_reference type
+  void x(const D& d);
+};
+}
+
+// CHECK-NOT: DW_TAG_variable
+NS::C c;
+NS::D d;
+NS::E e;
Index: test/Driver/debug-options.c
===================================================================
--- test/Driver/debug-options.c	(revision 155349)
+++ test/Driver/debug-options.c	(working copy)
@@ -7,6 +7,8 @@
 // RUN: %clang -### -c -ganything %s 2>&1 | FileCheck -check-prefix=GANY %s
 // RUN: %clang -### -c -ggdb %s 2>&1 | FileCheck -check-prefix=GGDB %s
 // RUN: %clang -### -c -gfoo %s 2>&1 | FileCheck -check-prefix=GFOO %s
+// RUN: %clang -### -c -gline-tables-only %s 2>&1 \
+// RUN:             | FileCheck -check-prefix=GLTO %s
 //
 // G: "-cc1"
 // G: "-g"
@@ -25,3 +27,6 @@
 //
 // GFOO: "-cc1"
 // GFOO-NOT: "-g"
+//
+// GLTO: "-cc1"
+// GLTO: "-g"
Index: test/CodeGen/debug-info-gline-tables-only.c
===================================================================
--- test/CodeGen/debug-info-gline-tables-only.c	(revision 0)
+++ test/CodeGen/debug-info-gline-tables-only.c	(revision 0)
@@ -0,0 +1,34 @@
+// RUN: %clang_cc1 %s -gline-tables-only -S -emit-llvm -o - | FileCheck %s
+// Checks that clang with "-gline-tables-only" doesn't emit debug info
+// for variables and types.
+
+// CHECK-NOT: DW_TAG_variable
+int global = 42;
+
+// CHECK-NOT: DW_TAG_typedef
+// CHECK-NOT: DW_TAG_const_type
+// CHECK-NOT: DW_TAG_pointer_type
+// CHECK-NOT: DW_TAG_array_type
+typedef const char* constCharPtrArray[10];
+
+// CHECK-NOT: DW_TAG_structure_type
+struct S {
+  // CHECK-NOT: DW_TAG_member
+  char a;
+  double b;
+  constCharPtrArray c;
+};
+
+// CHECK-NOT: DW_TAG_enumerator
+// CHECK-NOT: DW_TAG_enumeration_type
+enum E { ZERO = 0, ONE = 1 };
+
+// CHECK-NOT: DW_TAG_subroutine_type
+// CHECK-NOT: DW_TAG_arg_variable
+int sum(int p, int q) {
+  // CHECK-NOT: DW_TAG_auto_variable
+  int r = p + q;
+  struct S s;
+  enum E e;
+  return r;
+}
Index: include/clang/Frontend/CodeGenOptions.h
===================================================================
--- include/clang/Frontend/CodeGenOptions.h	(revision 155349)
+++ include/clang/Frontend/CodeGenOptions.h	(working copy)
@@ -44,6 +44,9 @@
   unsigned DataSections      : 1; /// Set when -fdata-sections is enabled
   unsigned DebugInfo         : 1; /// Should generate debug info (-g).
   unsigned LimitDebugInfo    : 1; /// Limit generated debug info to reduce size.
+  unsigned DebugLineTablesOnly : 1; /// Emit only debug info necessary for
+                                    /// generating line number tables
+                                    /// (-gline-tables-only).
   unsigned DisableFPElim     : 1; /// Set when -fomit-frame-pointer is enabled.
   unsigned DisableLLVMOpts   : 1; /// Don't run any optimizations, for use in
                                   /// getting .bc files that correspond to the
@@ -171,6 +174,7 @@
     DataSections = 0;
     DebugInfo = 0;
     LimitDebugInfo = 0;
+    DebugLineTablesOnly = 0;
     DisableFPElim = 0;
     DisableLLVMOpts = 0;
     DisableRedZone = 0;
Index: include/clang/Driver/CC1Options.td
===================================================================
--- include/clang/Driver/CC1Options.td	(revision 155349)
+++ include/clang/Driver/CC1Options.td	(working copy)
@@ -152,6 +152,8 @@
 def fforbid_guard_variables : Flag<"-fforbid-guard-variables">,
   HelpText<"Emit an error if a C++ static local initializer would need a guard variable">;
 def g : Flag<"-g">, HelpText<"Generate source level debug information">;
+def gline_tables_only : Flag<"-gline-tables-only">,
+  HelpText<"Emit debug line number tables only">;
 def fno_dwarf2_cfi_asm : Flag<"-fno-dwarf2-cfi-asm">,
   HelpText<"Don't use the cfi directives">;
 def fno_dwarf_directory_asm : Flag<"-fno-dwarf-directory-asm">,
Index: include/clang/Driver/Options.td
===================================================================
--- include/clang/Driver/Options.td	(revision 155349)
+++ include/clang/Driver/Options.td	(working copy)
@@ -568,6 +568,7 @@
 def gstabs2 : Flag<"-gstabs2">, Group<g_Group>;
 def gused : Flag<"-gused">, Group<g_Group>;
 def g_Flag : Flag<"-g">, Group<g_Group>;
+def gline_tables_only : Flag<"-gline-tables-only">, Group<g_Group>;
 def headerpad__max__install__names : Joined<"-headerpad_max_install_names">;
 def index_header_map : Flag<"-index-header-map">;
 def idirafter : JoinedOrSeparate<"-idirafter">, Group<clang_i_Group>;
Index: lib/Frontend/CompilerInvocation.cpp
===================================================================
--- lib/Frontend/CompilerInvocation.cpp	(revision 155349)
+++ lib/Frontend/CompilerInvocation.cpp	(working copy)
@@ -183,6 +183,8 @@
 static void CodeGenOptsToArgs(const CodeGenOptions &Opts, ToArgsList &Res) {
   if (Opts.DebugInfo)
     Res.push_back("-g");
+  if (Opts.DebugLineTablesOnly)
+    Res.push_back("-gline-tables-only");
   if (Opts.DisableLLVMOpts)
     Res.push_back("-disable-llvm-optzns");
   if (Opts.DisableRedZone)
@@ -1086,9 +1088,11 @@
   Opts.Inlining = Args.hasArg(OPT_fno_inline_functions) ? 
     CodeGenOptions::OnlyAlwaysInlining : Opts.Inlining;
 
-  Opts.DebugInfo = Args.hasArg(OPT_g);
+  Opts.DebugInfo = Args.hasArg(OPT_g) ||
+                   Args.hasArg(OPT_gline_tables_only);
   Opts.LimitDebugInfo = !Args.hasArg(OPT_fno_limit_debug_info)
     || Args.hasArg(OPT_flimit_debug_info);
+  Opts.DebugLineTablesOnly = Args.hasArg(OPT_gline_tables_only);
   Opts.DisableLLVMOpts = Args.hasArg(OPT_disable_llvm_optzns);
   Opts.DisableRedZone = Args.hasArg(OPT_disable_red_zone);
   Opts.ForbidGuardVariables = Args.hasArg(OPT_fforbid_guard_variables);
Index: lib/Driver/Tools.cpp
===================================================================
--- lib/Driver/Tools.cpp	(revision 155349)
+++ lib/Driver/Tools.cpp	(working copy)
@@ -1807,6 +1807,8 @@
     if (!A->getOption().matches(options::OPT_g0)) {
       CmdArgs.push_back("-g");
     }
+  if (Args.hasArg(options::OPT_gline_tables_only))
+    CmdArgs.push_back("-gline-tables-only");
 
   Args.AddAllArgs(CmdArgs, options::OPT_ffunction_sections);
   Args.AddAllArgs(CmdArgs, options::OPT_fdata_sections);
Index: lib/CodeGen/CodeGenFunction.cpp
===================================================================
--- lib/CodeGen/CodeGenFunction.cpp	(revision 155349)
+++ lib/CodeGen/CodeGenFunction.cpp	(working copy)
@@ -1087,7 +1087,8 @@
                                               llvm::Constant *Init) {
   assert (Init && "Invalid DeclRefExpr initializer!");
   if (CGDebugInfo *Dbg = getDebugInfo())
-    Dbg->EmitGlobalVariable(E->getDecl(), Init);
+    if (!CGM.getCodeGenOpts().DebugLineTablesOnly)
+      Dbg->EmitGlobalVariable(E->getDecl(), Init);
 }
 
 CodeGenFunction::PeepholeProtection
Index: lib/CodeGen/CGExprScalar.cpp
===================================================================
--- lib/CodeGen/CGExprScalar.cpp	(revision 155349)
+++ lib/CodeGen/CGExprScalar.cpp	(working copy)
@@ -801,7 +801,8 @@
   // Emit debug info for aggregate now, if it was delayed to reduce 
   // debug info size.
   CGDebugInfo *DI = CGF.getDebugInfo();
-  if (DI && CGF.CGM.getCodeGenOpts().LimitDebugInfo) {
+  if (DI && CGF.CGM.getCodeGenOpts().LimitDebugInfo &&
+      !CGF.CGM.getCodeGenOpts().DebugLineTablesOnly) {
     QualType PQTy = E->getBase()->IgnoreParenImpCasts()->getType();
     if (const PointerType * PTy = dyn_cast<PointerType>(PQTy))
       if (FieldDecl *M = dyn_cast<FieldDecl>(E->getMemberDecl()))
Index: lib/CodeGen/CodeGenModule.cpp
===================================================================
--- lib/CodeGen/CodeGenModule.cpp	(revision 155349)
+++ lib/CodeGen/CodeGenModule.cpp	(working copy)
@@ -1604,7 +1604,8 @@
 
   // Emit global variable debug information.
   if (CGDebugInfo *DI = getModuleDebugInfo())
-    DI->EmitGlobalVariable(GV, D);
+    if (!getCodeGenOpts().DebugLineTablesOnly)
+      DI->EmitGlobalVariable(GV, D);
 }
 
 llvm::GlobalValue::LinkageTypes
Index: lib/CodeGen/CGExprCXX.cpp
===================================================================
--- lib/CodeGen/CGExprCXX.cpp	(revision 155349)
+++ lib/CodeGen/CGExprCXX.cpp	(working copy)
@@ -179,8 +179,9 @@
   const CXXMethodDecl *MD = cast<CXXMethodDecl>(ME->getMemberDecl());
 
   CGDebugInfo *DI = getDebugInfo();
-  if (DI && CGM.getCodeGenOpts().LimitDebugInfo
-      && !isa<CallExpr>(ME->getBase())) {
+  if (DI && CGM.getCodeGenOpts().LimitDebugInfo &&
+      !CGM.getCodeGenOpts().DebugLineTablesOnly &&
+      !isa<CallExpr>(ME->getBase())) {
     QualType PQTy = ME->getBase()->IgnoreParenImpCasts()->getType();
     if (const PointerType * PTy = dyn_cast<PointerType>(PQTy)) {
       DI->getOrCreateRecordType(PTy->getPointeeType(), 
Index: lib/CodeGen/CGDebugInfo.cpp
===================================================================
--- lib/CodeGen/CGDebugInfo.cpp	(revision 155349)
+++ lib/CodeGen/CGDebugInfo.cpp	(working copy)
@@ -907,6 +907,7 @@
 CGDebugInfo::CreateCXXMemberFunction(const CXXMethodDecl *Method,
                                      llvm::DIFile Unit,
                                      llvm::DIType RecordTy) {
+  assert(!CGM.getCodeGenOpts().DebugLineTablesOnly);
   bool IsCtorOrDtor = 
     isa<CXXConstructorDecl>(Method) || isa<CXXDestructorDecl>(Method);
   
@@ -1989,7 +1990,7 @@
   const Decl *D = GD.getDecl();
   // Use the location of the declaration.
   SourceLocation Loc = D->getLocation();
-  
+
   unsigned Flags = 0;
   llvm::DIFile Unit = getOrCreateFile(Loc);
   llvm::DIDescriptor FDContext(Unit);
@@ -2013,18 +2014,20 @@
       LinkageName = CGM.getMangledName(GD);
       Flags |= llvm::DIDescriptor::FlagPrototyped;
     }
-    if (LinkageName == Name)
+    if (LinkageName == Name || CGM.getCodeGenOpts().DebugLineTablesOnly)
       LinkageName = StringRef();
 
-    if (const NamespaceDecl *NSDecl =
-        dyn_cast_or_null<NamespaceDecl>(FD->getDeclContext()))
-      FDContext = getOrCreateNameSpace(NSDecl);
-    else if (const RecordDecl *RDecl =
-             dyn_cast_or_null<RecordDecl>(FD->getDeclContext()))
-      FDContext = getContextDescriptor(cast<Decl>(RDecl->getDeclContext()));
+    if (!CGM.getCodeGenOpts().DebugLineTablesOnly) {
+      if (const NamespaceDecl *NSDecl =
+          dyn_cast_or_null<NamespaceDecl>(FD->getDeclContext()))
+        FDContext = getOrCreateNameSpace(NSDecl);
+      else if (const RecordDecl *RDecl =
+               dyn_cast_or_null<RecordDecl>(FD->getDeclContext()))
+        FDContext = getContextDescriptor(cast<Decl>(RDecl->getDeclContext()));
 
-    // Collect template parameters.
-    TParamsArray = CollectFunctionTemplateParams(FD, Unit);
+      // Collect template parameters.
+      TParamsArray = CollectFunctionTemplateParams(FD, Unit);
+    }
   } else if (const ObjCMethodDecl *OMD = dyn_cast<ObjCMethodDecl>(D)) {
     Name = getObjCMethodName(OMD);
     Flags |= llvm::DIDescriptor::FlagPrototyped;
@@ -2040,14 +2043,22 @@
   if (D->isImplicit())
     Flags |= llvm::DIDescriptor::FlagArtificial;
 
-  llvm::DISubprogram SPDecl = getFunctionDeclaration(D);
-  llvm::DISubprogram SP =
-    DBuilder.createFunction(FDContext, Name, LinkageName, Unit,
-                            LineNo, getOrCreateFunctionType(D, FnType, Unit),
-                            Fn->hasInternalLinkage(), true/*definition*/,
-                            getLineNumber(CurLoc),
-                            Flags, CGM.getLangOpts().Optimize, Fn,
-                            TParamsArray, SPDecl);
+  llvm::DIType DIFnType;
+  llvm::DISubprogram SPDecl;
+  if (!CGM.getCodeGenOpts().DebugLineTablesOnly) {
+    // FIXME(samsonov): In fact we should create valid DIFnType for
+    // DebugLineTablesOnly as well: otherwise llvm::DISubprogram::Verify()
+    // returns "false", and SP DIE lacks DW_AT_decl_line field.
+    DIFnType = getOrCreateFunctionType(D, FnType, Unit);
+    SPDecl = getFunctionDeclaration(D);
+  }
+  llvm::DISubprogram SP;
+  SP = DBuilder.createFunction(FDContext, Name, LinkageName, Unit,
+                               LineNo, DIFnType,
+                               Fn->hasInternalLinkage(), true/*definition*/,
+                               getLineNumber(CurLoc), Flags,
+                               CGM.getLangOpts().Optimize,
+                               Fn, TParamsArray, SPDecl);
 
   // Push function on region stack.
   llvm::MDNode *SPN = SP;
@@ -2205,6 +2216,7 @@
 void CGDebugInfo::EmitDeclare(const VarDecl *VD, unsigned Tag,
                               llvm::Value *Storage, 
                               unsigned ArgNo, CGBuilderTy &Builder) {
+  assert(!CGM.getCodeGenOpts().DebugLineTablesOnly);
   assert(!LexicalBlockStack.empty() && "Region stack mismatch, stack empty!");
 
   llvm::DIFile Unit = getOrCreateFile(VD->getLocation());
@@ -2321,12 +2333,14 @@
 void CGDebugInfo::EmitDeclareOfAutoVariable(const VarDecl *VD,
                                             llvm::Value *Storage,
                                             CGBuilderTy &Builder) {
+  assert(!CGM.getCodeGenOpts().DebugLineTablesOnly);
   EmitDeclare(VD, llvm::dwarf::DW_TAG_auto_variable, Storage, 0, Builder);
 }
 
 void CGDebugInfo::EmitDeclareOfBlockDeclRefVariable(
   const VarDecl *VD, llvm::Value *Storage, CGBuilderTy &Builder,
   const CGBlockInfo &blockInfo) {
+  assert(!CGM.getCodeGenOpts().DebugLineTablesOnly);
   assert(!LexicalBlockStack.empty() && "Region stack mismatch, stack empty!");
   
   if (Builder.GetInsertBlock() == 0)
@@ -2387,6 +2401,7 @@
 void CGDebugInfo::EmitDeclareOfArgVariable(const VarDecl *VD, llvm::Value *AI,
                                            unsigned ArgNo,
                                            CGBuilderTy &Builder) {
+  assert(!CGM.getCodeGenOpts().DebugLineTablesOnly);
   EmitDeclare(VD, llvm::dwarf::DW_TAG_arg_variable, AI, ArgNo, Builder);
 }
 
@@ -2403,6 +2418,7 @@
 void CGDebugInfo::EmitDeclareOfBlockLiteralArgVariable(const CGBlockInfo &block,
                                                        llvm::Value *addr,
                                                        CGBuilderTy &Builder) {
+  assert(!CGM.getCodeGenOpts().DebugLineTablesOnly);
   ASTContext &C = CGM.getContext();
   const BlockDecl *blockDecl = block.getBlockDecl();
 
@@ -2547,6 +2563,7 @@
 /// EmitGlobalVariable - Emit information about a global variable.
 void CGDebugInfo::EmitGlobalVariable(llvm::GlobalVariable *Var,
                                      const VarDecl *D) {
+  assert(!CGM.getCodeGenOpts().DebugLineTablesOnly);
   // Create global variable debug descriptor.
   llvm::DIFile Unit = getOrCreateFile(D->getLocation());
   unsigned LineNo = getLineNumber(D->getLocation());
@@ -2582,6 +2599,7 @@
 /// EmitGlobalVariable - Emit information about an objective-c interface.
 void CGDebugInfo::EmitGlobalVariable(llvm::GlobalVariable *Var,
                                      ObjCInterfaceDecl *ID) {
+  assert(!CGM.getCodeGenOpts().DebugLineTablesOnly);
   // Create global variable debug descriptor.
   llvm::DIFile Unit = getOrCreateFile(ID->getLocation());
   unsigned LineNo = getLineNumber(ID->getLocation());
@@ -2609,6 +2627,7 @@
 /// EmitGlobalVariable - Emit global variable's debug info.
 void CGDebugInfo::EmitGlobalVariable(const ValueDecl *VD, 
                                      llvm::Constant *Init) {
+  assert(!CGM.getCodeGenOpts().DebugLineTablesOnly);
   // Create the descriptor for the variable.
   llvm::DIFile Unit = getOrCreateFile(VD->getLocation());
   StringRef Name = VD->getName();
Index: lib/CodeGen/CGClass.cpp
===================================================================
--- lib/CodeGen/CGClass.cpp	(revision 155349)
+++ lib/CodeGen/CGClass.cpp	(working copy)
@@ -1227,7 +1227,8 @@
                                         CallExpr::const_arg_iterator ArgEnd) {
 
   CGDebugInfo *DI = getDebugInfo();
-  if (DI && CGM.getCodeGenOpts().LimitDebugInfo) {
+  if (DI && CGM.getCodeGenOpts().LimitDebugInfo &&
+      !CGM.getCodeGenOpts().DebugLineTablesOnly) {
     // If debug info for this class has not been emitted then this is the
     // right time to do so.
     const CXXRecordDecl *Parent = D->getParent();
Index: lib/CodeGen/CGDecl.cpp
===================================================================
--- lib/CodeGen/CGDecl.cpp	(revision 155349)
+++ lib/CodeGen/CGDecl.cpp	(working copy)
@@ -326,7 +326,7 @@
 
   // Emit global variable debug descriptor for static vars.
   CGDebugInfo *DI = getDebugInfo();
-  if (DI) {
+  if (DI && !CGM.getCodeGenOpts().DebugLineTablesOnly) {
     DI->setLocation(D.getLocation());
     DI->EmitGlobalVariable(var, &D);
   }
@@ -897,11 +897,13 @@
   // Emit debug info for local var declaration.
   if (HaveInsertPoint())
     if (CGDebugInfo *DI = getDebugInfo()) {
-      DI->setLocation(D.getLocation());
-      if (Target.useGlobalsForAutomaticVariables()) {
-        DI->EmitGlobalVariable(static_cast<llvm::GlobalVariable *>(DeclPtr), &D);
-      } else
-        DI->EmitDeclareOfAutoVariable(&D, DeclPtr, Builder);
+      if (!CGM.getCodeGenOpts().DebugLineTablesOnly) {
+        DI->setLocation(D.getLocation());
+        if (Target.useGlobalsForAutomaticVariables()) {
+          DI->EmitGlobalVariable(static_cast<llvm::GlobalVariable *>(DeclPtr), &D);
+        } else
+          DI->EmitDeclareOfAutoVariable(&D, DeclPtr, Builder);
+      }
     }
 
   if (D.hasAttr<AnnotateAttr>())
@@ -1477,8 +1479,10 @@
       LocalDeclMap[&D] = Arg;
 
       if (CGDebugInfo *DI = getDebugInfo()) {
-        DI->setLocation(D.getLocation());
-        DI->EmitDeclareOfBlockLiteralArgVariable(*BlockInfo, Arg, Builder);
+        if (!CGM.getCodeGenOpts().DebugLineTablesOnly) {
+          DI->setLocation(D.getLocation());
+          DI->EmitDeclareOfBlockLiteralArgVariable(*BlockInfo, Arg, Builder);
+        }
       }
 
       return;
@@ -1556,8 +1560,11 @@
   DMEntry = DeclPtr;
 
   // Emit debug info for param declaration.
-  if (CGDebugInfo *DI = getDebugInfo())
-    DI->EmitDeclareOfArgVariable(&D, DeclPtr, ArgNo, Builder);
+  if (CGDebugInfo *DI = getDebugInfo()) {
+    if (!CGM.getCodeGenOpts().DebugLineTablesOnly) {
+      DI->EmitDeclareOfArgVariable(&D, DeclPtr, ArgNo, Builder);
+    }
+  }
 
   if (D.hasAttr<AnnotateAttr>())
       EmitVarAnnotations(&D, DeclPtr);
Index: lib/CodeGen/CGBlocks.cpp
===================================================================
--- lib/CodeGen/CGBlocks.cpp	(revision 155349)
+++ lib/CodeGen/CGBlocks.cpp	(working copy)
@@ -1130,15 +1130,17 @@
       const VarDecl *variable = ci->getVariable();
       DI->EmitLocation(Builder, variable->getLocation());
 
-      const CGBlockInfo::Capture &capture = blockInfo.getCapture(variable);
-      if (capture.isConstant()) {
-        DI->EmitDeclareOfAutoVariable(variable, LocalDeclMap[variable],
-                                      Builder);
-        continue;
+      if (!CGM.getCodeGenOpts().DebugLineTablesOnly) {
+        const CGBlockInfo::Capture &capture = blockInfo.getCapture(variable);
+        if (capture.isConstant()) {
+          DI->EmitDeclareOfAutoVariable(variable, LocalDeclMap[variable],
+                                        Builder);
+          continue;
+        }
+
+        DI->EmitDeclareOfBlockDeclRefVariable(variable, BlockPointer,
+                                              Builder, blockInfo);
       }
-
-      DI->EmitDeclareOfBlockDeclRefVariable(variable, BlockPointer,
-                                            Builder, blockInfo);
     }
   }
 
