diff options
-rw-r--r-- | clang/include/clang/Driver/Options.td | 2 | ||||
-rw-r--r-- | clang/include/clang/Frontend/CodeGenOptions.h | 2 | ||||
-rw-r--r-- | clang/lib/CodeGen/CGBlocks.cpp | 18 | ||||
-rw-r--r-- | clang/lib/CodeGen/CGDebugInfo.cpp | 60 | ||||
-rw-r--r-- | clang/lib/CodeGen/CGDecl.cpp | 30 | ||||
-rw-r--r-- | clang/lib/CodeGen/CodeGenFunction.cpp | 3 | ||||
-rw-r--r-- | clang/lib/CodeGen/CodeGenModule.cpp | 3 | ||||
-rw-r--r-- | clang/lib/Driver/Tools.cpp | 2 | ||||
-rw-r--r-- | clang/lib/Frontend/CompilerInvocation.cpp | 7 | ||||
-rw-r--r-- | clang/test/CodeGen/debug-info-gline-tables-only.c | 33 | ||||
-rw-r--r-- | clang/test/CodeGen/debug-info-gline-tables-only2.c | 13 | ||||
-rw-r--r-- | clang/test/CodeGenCXX/debug-info-gline-tables-only.cpp | 21 | ||||
-rw-r--r-- | clang/test/Driver/debug-options.c | 5 |
13 files changed, 161 insertions, 38 deletions
diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td index 4ca5e959459..5d20e21dac7 100644 --- a/clang/include/clang/Driver/Options.td +++ b/clang/include/clang/Driver/Options.td @@ -673,6 +673,8 @@ def gstabs2 : Flag<"-gstabs2">, Group<g_Group>; def gused : Flag<"-gused">, Group<g_Group>; def g_Flag : Flag<"-g">, Group<g_Group>, HelpText<"Generate source level debug information">, Flags<[CC1Option]>; +def gline_tables_only : Flag<"-gline-tables-only">, Group<g_Group>, + HelpText<"Emit debug line number tables only">, Flags<[CC1Option]>; def headerpad__max__install__names : Joined<"-headerpad_max_install_names">; def help : Flag<"-help">, Flags<[CC1Option]>, HelpText<"Display available options">; diff --git a/clang/include/clang/Frontend/CodeGenOptions.h b/clang/include/clang/Frontend/CodeGenOptions.h index 168dd267835..3181c0affd7 100644 --- a/clang/include/clang/Frontend/CodeGenOptions.h +++ b/clang/include/clang/Frontend/CodeGenOptions.h @@ -37,6 +37,8 @@ public: enum DebugInfoKind { NoDebugInfo, // Don't generate debug info. + DebugLineTablesOnly, // Emit only debug info necessary for generating + // line number tables (-gline-tables-only). LimitedDebugInfo, // Limit generated debug info to reduce size // (-flimit-debug-info). FullDebugInfo // Generate complete debug info. diff --git a/clang/lib/CodeGen/CGBlocks.cpp b/clang/lib/CodeGen/CGBlocks.cpp index 1a1fe65ff88..dad8e7ea7cf 100644 --- a/clang/lib/CodeGen/CGBlocks.cpp +++ b/clang/lib/CodeGen/CGBlocks.cpp @@ -1134,15 +1134,17 @@ CodeGenFunction::GenerateBlockFunction(GlobalDecl GD, 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().DebugInfo >= CodeGenOptions::LimitedDebugInfo) { + 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); + } } } diff --git a/clang/lib/CodeGen/CGDebugInfo.cpp b/clang/lib/CodeGen/CGDebugInfo.cpp index af6e340b9da..b3fc0a45cef 100644 --- a/clang/lib/CodeGen/CGDebugInfo.cpp +++ b/clang/lib/CodeGen/CGDebugInfo.cpp @@ -1176,6 +1176,7 @@ CollectVTableInfo(const CXXRecordDecl *RD, llvm::DIFile Unit, /// getOrCreateRecordType - Emit record type's standalone debug info. llvm::DIType CGDebugInfo::getOrCreateRecordType(QualType RTy, SourceLocation Loc) { + assert(CGM.getCodeGenOpts().DebugInfo >= CodeGenOptions::LimitedDebugInfo); llvm::DIType T = getOrCreateType(RTy, getOrCreateFile(Loc)); return T; } @@ -1184,6 +1185,7 @@ llvm::DIType CGDebugInfo::getOrCreateRecordType(QualType RTy, /// debug info. llvm::DIType CGDebugInfo::getOrCreateInterfaceType(QualType D, SourceLocation Loc) { + assert(CGM.getCodeGenOpts().DebugInfo >= CodeGenOptions::LimitedDebugInfo); llvm::DIType T = getOrCreateType(D, getOrCreateFile(Loc)); DBuilder.retainType(T); return T; @@ -2012,18 +2014,21 @@ void CGDebugInfo::EmitFunctionStart(GlobalDecl GD, QualType FnType, LinkageName = CGM.getMangledName(GD); Flags |= llvm::DIDescriptor::FlagPrototyped; } - if (LinkageName == Name) + if (LinkageName == Name || + CGM.getCodeGenOpts().DebugInfo <= CodeGenOptions::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().DebugInfo >= CodeGenOptions::LimitedDebugInfo) { + 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; @@ -2039,14 +2044,27 @@ void CGDebugInfo::EmitFunctionStart(GlobalDecl GD, QualType FnType, 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().DebugInfo >= CodeGenOptions::LimitedDebugInfo) { + DIFnType = getOrCreateFunctionType(D, FnType, Unit); + SPDecl = getFunctionDeclaration(D); + } else { + // Create fake but valid subroutine type. Otherwise + // llvm::DISubprogram::Verify() would return false, and + // subprogram DIE will miss DW_AT_decl_file and + // DW_AT_decl_line fields. + SmallVector<llvm::Value*, 16> Elts; + llvm::DIArray EltTypeArray = DBuilder.getOrCreateArray(Elts); + DIFnType = DBuilder.createSubroutineType(Unit, EltTypeArray); + } + 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; @@ -2204,6 +2222,7 @@ llvm::DIType CGDebugInfo::EmitTypeForVarWithBlocksAttr(const ValueDecl *VD, void CGDebugInfo::EmitDeclare(const VarDecl *VD, unsigned Tag, llvm::Value *Storage, unsigned ArgNo, CGBuilderTy &Builder) { + assert(CGM.getCodeGenOpts().DebugInfo >= CodeGenOptions::LimitedDebugInfo); assert(!LexicalBlockStack.empty() && "Region stack mismatch, stack empty!"); llvm::DIFile Unit = getOrCreateFile(VD->getLocation()); @@ -2320,12 +2339,14 @@ void CGDebugInfo::EmitDeclare(const VarDecl *VD, unsigned Tag, void CGDebugInfo::EmitDeclareOfAutoVariable(const VarDecl *VD, llvm::Value *Storage, CGBuilderTy &Builder) { + assert(CGM.getCodeGenOpts().DebugInfo >= CodeGenOptions::LimitedDebugInfo); 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().DebugInfo >= CodeGenOptions::LimitedDebugInfo); assert(!LexicalBlockStack.empty() && "Region stack mismatch, stack empty!"); if (Builder.GetInsertBlock() == 0) @@ -2386,6 +2407,7 @@ void CGDebugInfo::EmitDeclareOfBlockDeclRefVariable( void CGDebugInfo::EmitDeclareOfArgVariable(const VarDecl *VD, llvm::Value *AI, unsigned ArgNo, CGBuilderTy &Builder) { + assert(CGM.getCodeGenOpts().DebugInfo >= CodeGenOptions::LimitedDebugInfo); EmitDeclare(VD, llvm::dwarf::DW_TAG_arg_variable, AI, ArgNo, Builder); } @@ -2402,6 +2424,7 @@ namespace { void CGDebugInfo::EmitDeclareOfBlockLiteralArgVariable(const CGBlockInfo &block, llvm::Value *addr, CGBuilderTy &Builder) { + assert(CGM.getCodeGenOpts().DebugInfo >= CodeGenOptions::LimitedDebugInfo); ASTContext &C = CGM.getContext(); const BlockDecl *blockDecl = block.getBlockDecl(); @@ -2546,6 +2569,7 @@ void CGDebugInfo::EmitDeclareOfBlockLiteralArgVariable(const CGBlockInfo &block, /// EmitGlobalVariable - Emit information about a global variable. void CGDebugInfo::EmitGlobalVariable(llvm::GlobalVariable *Var, const VarDecl *D) { + assert(CGM.getCodeGenOpts().DebugInfo >= CodeGenOptions::LimitedDebugInfo); // Create global variable debug descriptor. llvm::DIFile Unit = getOrCreateFile(D->getLocation()); unsigned LineNo = getLineNumber(D->getLocation()); @@ -2581,6 +2605,7 @@ void CGDebugInfo::EmitGlobalVariable(llvm::GlobalVariable *Var, /// EmitGlobalVariable - Emit information about an objective-c interface. void CGDebugInfo::EmitGlobalVariable(llvm::GlobalVariable *Var, ObjCInterfaceDecl *ID) { + assert(CGM.getCodeGenOpts().DebugInfo >= CodeGenOptions::LimitedDebugInfo); // Create global variable debug descriptor. llvm::DIFile Unit = getOrCreateFile(ID->getLocation()); unsigned LineNo = getLineNumber(ID->getLocation()); @@ -2608,6 +2633,7 @@ void CGDebugInfo::EmitGlobalVariable(llvm::GlobalVariable *Var, /// EmitGlobalVariable - Emit global variable's debug info. void CGDebugInfo::EmitGlobalVariable(const ValueDecl *VD, llvm::Constant *Init) { + assert(CGM.getCodeGenOpts().DebugInfo >= CodeGenOptions::LimitedDebugInfo); // Create the descriptor for the variable. llvm::DIFile Unit = getOrCreateFile(VD->getLocation()); StringRef Name = VD->getName(); diff --git a/clang/lib/CodeGen/CGDecl.cpp b/clang/lib/CodeGen/CGDecl.cpp index 644777963b2..4d4b57904c4 100644 --- a/clang/lib/CodeGen/CGDecl.cpp +++ b/clang/lib/CodeGen/CGDecl.cpp @@ -326,7 +326,8 @@ void CodeGenFunction::EmitStaticVarDecl(const VarDecl &D, // Emit global variable debug descriptor for static vars. CGDebugInfo *DI = getDebugInfo(); - if (DI) { + if (DI && + CGM.getCodeGenOpts().DebugInfo >= CodeGenOptions::LimitedDebugInfo) { DI->setLocation(D.getLocation()); DI->EmitGlobalVariable(var, &D); } @@ -897,11 +898,14 @@ CodeGenFunction::EmitAutoVarAlloca(const VarDecl &D) { // 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().DebugInfo >= CodeGenOptions::LimitedDebugInfo) { + 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 +1481,11 @@ void CodeGenFunction::EmitParmDecl(const VarDecl &D, llvm::Value *Arg, LocalDeclMap[&D] = Arg; if (CGDebugInfo *DI = getDebugInfo()) { - DI->setLocation(D.getLocation()); - DI->EmitDeclareOfBlockLiteralArgVariable(*BlockInfo, Arg, Builder); + if (CGM.getCodeGenOpts().DebugInfo >= + CodeGenOptions::LimitedDebugInfo) { + DI->setLocation(D.getLocation()); + DI->EmitDeclareOfBlockLiteralArgVariable(*BlockInfo, Arg, Builder); + } } return; @@ -1556,8 +1563,11 @@ void CodeGenFunction::EmitParmDecl(const VarDecl &D, llvm::Value *Arg, 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().DebugInfo >= CodeGenOptions::LimitedDebugInfo) { + DI->EmitDeclareOfArgVariable(&D, DeclPtr, ArgNo, Builder); + } + } if (D.hasAttr<AnnotateAttr>()) EmitVarAnnotations(&D, DeclPtr); diff --git a/clang/lib/CodeGen/CodeGenFunction.cpp b/clang/lib/CodeGen/CodeGenFunction.cpp index fd787394d78..dfb04b42aa5 100644 --- a/clang/lib/CodeGen/CodeGenFunction.cpp +++ b/clang/lib/CodeGen/CodeGenFunction.cpp @@ -1087,7 +1087,8 @@ void CodeGenFunction::EmitDeclRefExprDbgValue(const DeclRefExpr *E, llvm::Constant *Init) { assert (Init && "Invalid DeclRefExpr initializer!"); if (CGDebugInfo *Dbg = getDebugInfo()) - Dbg->EmitGlobalVariable(E->getDecl(), Init); + if (CGM.getCodeGenOpts().DebugInfo >= CodeGenOptions::LimitedDebugInfo) + Dbg->EmitGlobalVariable(E->getDecl(), Init); } CodeGenFunction::PeepholeProtection diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp index 660cc8bae9a..775f500fdb1 100644 --- a/clang/lib/CodeGen/CodeGenModule.cpp +++ b/clang/lib/CodeGen/CodeGenModule.cpp @@ -1606,7 +1606,8 @@ void CodeGenModule::EmitGlobalVarDefinition(const VarDecl *D) { // Emit global variable debug information. if (CGDebugInfo *DI = getModuleDebugInfo()) - DI->EmitGlobalVariable(GV, D); + if (getCodeGenOpts().DebugInfo >= CodeGenOptions::LimitedDebugInfo) + DI->EmitGlobalVariable(GV, D); } llvm::GlobalValue::LinkageTypes diff --git a/clang/lib/Driver/Tools.cpp b/clang/lib/Driver/Tools.cpp index 7a9d1cf0eba..9448425a424 100644 --- a/clang/lib/Driver/Tools.cpp +++ b/clang/lib/Driver/Tools.cpp @@ -1816,6 +1816,8 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, 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); diff --git a/clang/lib/Frontend/CompilerInvocation.cpp b/clang/lib/Frontend/CompilerInvocation.cpp index e8345fdfd76..0635be66673 100644 --- a/clang/lib/Frontend/CompilerInvocation.cpp +++ b/clang/lib/Frontend/CompilerInvocation.cpp @@ -184,6 +184,9 @@ static void CodeGenOptsToArgs(const CodeGenOptions &Opts, ToArgsList &Res) { switch (Opts.DebugInfo) { case CodeGenOptions::NoDebugInfo: break; + case CodeGenOptions::DebugLineTablesOnly: + Res.push_back("-gline-tables-only"); + break; case CodeGenOptions::LimitedDebugInfo: Res.push_back("-g"); Res.push_back("-flimit-debug-info"); @@ -1148,7 +1151,9 @@ static bool ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args, InputKind IK, Opts.Inlining = Args.hasArg(OPT_fno_inline_functions) ? CodeGenOptions::OnlyAlwaysInlining : Opts.Inlining; - if (Args.hasArg(OPT_g_Flag)) { + if (Args.hasArg(OPT_gline_tables_only)) { + Opts.DebugInfo = CodeGenOptions::DebugLineTablesOnly; + } else if (Args.hasArg(OPT_g_Flag)) { if (Args.hasFlag(OPT_flimit_debug_info, OPT_fno_limit_debug_info, true)) Opts.DebugInfo = CodeGenOptions::LimitedDebugInfo; else diff --git a/clang/test/CodeGen/debug-info-gline-tables-only.c b/clang/test/CodeGen/debug-info-gline-tables-only.c new file mode 100644 index 00000000000..067d8e77218 --- /dev/null +++ b/clang/test/CodeGen/debug-info-gline-tables-only.c @@ -0,0 +1,33 @@ +// 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_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; +} diff --git a/clang/test/CodeGen/debug-info-gline-tables-only2.c b/clang/test/CodeGen/debug-info-gline-tables-only2.c new file mode 100644 index 00000000000..8e9cc64e0d6 --- /dev/null +++ b/clang/test/CodeGen/debug-info-gline-tables-only2.c @@ -0,0 +1,13 @@ +// RUN: %clang_cc1 %s -gline-tables-only -S -emit-llvm -o - | FileCheck %s +// Checks that clang with "-gline-tables-only" emits metadata for +// compile unit, subprogram and file. + +int main() { + // CHECK: ret i32 0, !dbg + return 0; +} + +// CHECK: !llvm.dbg.cu = !{!0} +// CHECK: DW_TAG_compile_unit +// CHECK: {{.*main.* DW_TAG_subprogram}} +// CHECK: DW_TAG_file_type diff --git a/clang/test/CodeGenCXX/debug-info-gline-tables-only.cpp b/clang/test/CodeGenCXX/debug-info-gline-tables-only.cpp new file mode 100644 index 00000000000..8d2e63d6777 --- /dev/null +++ b/clang/test/CodeGenCXX/debug-info-gline-tables-only.cpp @@ -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; diff --git a/clang/test/Driver/debug-options.c b/clang/test/Driver/debug-options.c index 5dad8e93824..b0ad2857357 100644 --- a/clang/test/Driver/debug-options.c +++ b/clang/test/Driver/debug-options.c @@ -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" |