From: David Blaikie Date: Thu, 1 Aug 2013 20:57:40 +0000 (+0000) Subject: DebugInfo: Don't prefer declarations over definitions in -flimit-debug-info in C X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=79af384d72355dca4174e5a9ee391d38226896bc;p=platform%2Fupstream%2Fllvm.git DebugInfo: Don't prefer declarations over definitions in -flimit-debug-info in C Without an ODR, the -flimit-debug-info debug info size optimization of emitting declarations for fully defined types when only a declaration is needed by the TU, is incorrect. Emit the full definition whenever it's available in non-C++. llvm-svn: 187611 --- diff --git a/clang/lib/CodeGen/CGDebugInfo.cpp b/clang/lib/CodeGen/CGDebugInfo.cpp index 0e3b98d..c903a2c 100644 --- a/clang/lib/CodeGen/CGDebugInfo.cpp +++ b/clang/lib/CodeGen/CGDebugInfo.cpp @@ -1422,7 +1422,7 @@ llvm::DIType CGDebugInfo::CreateType(const RecordType *Ty, bool Declaration) { // Limited debug info should only remove struct definitions that can // safely be replaced by a forward declaration in the source code. if (DebugKind <= CodeGenOptions::LimitedDebugInfo && Declaration && - !RD->isCompleteDefinitionRequired()) { + !RD->isCompleteDefinitionRequired() && CGM.getLangOpts().CPlusPlus) { // FIXME: This implementation is problematic; there are some test // cases where we violate the above principle, such as // test/CodeGen/debug-info-records.c . @@ -1951,7 +1951,8 @@ llvm::DIType CGDebugInfo::getCompletedTypeOrNull(QualType Ty) { void CGDebugInfo::completeFwdDecl(const RecordDecl &RD) { // In limited debug info we only want to do this if the complete type was // required. - if (DebugKind <= CodeGenOptions::LimitedDebugInfo) + if (DebugKind <= CodeGenOptions::LimitedDebugInfo && + CGM.getLangOpts().CPlusPlus) return; QualType QTy = CGM.getContext().getRecordType(&RD); diff --git a/clang/test/CodeGen/debug-info-limited.c b/clang/test/CodeGen/debug-info-limited.c new file mode 100644 index 0000000..7333452 --- /dev/null +++ b/clang/test/CodeGen/debug-info-limited.c @@ -0,0 +1,11 @@ +// RUN: %clang -flimit-debug-info -emit-llvm -g -S %s -o - | FileCheck %s + +// Ensure we emit the full definition of 'foo' even though only its declaration +// is needed, since C has no ODR to ensure that the definition will be the same +// in whatever TU actually uses/requires the definition of 'foo'. +// CHECK: ; [ DW_TAG_structure_type ] [foo] {{.*}} [def] + +struct foo { +}; + +struct foo *f; diff --git a/clang/test/CodeGenCXX/debug-info-limited.cpp b/clang/test/CodeGenCXX/debug-info-limited.cpp index f15dce5..12c9c04 100644 --- a/clang/test/CodeGenCXX/debug-info-limited.cpp +++ b/clang/test/CodeGenCXX/debug-info-limited.cpp @@ -1,7 +1,6 @@ -// RUN: %clang -emit-llvm -g -S %s -o - | FileCheck %s +// RUN: %clang -flimit-debug-info -emit-llvm -g -S %s -o - | FileCheck %s -// TAG_member is used to encode debug info for 'z' in A. -// CHECK: TAG_member +// CHECK: ; [ DW_TAG_class_type ] [A] {{.*}} [def] class A { public: int z; @@ -13,8 +12,7 @@ A *foo (A* x) { } // Verify that we're not emitting a full definition of B in limit debug mode. -// RUN: %clang -emit-llvm -g -flimit-debug-info -S %s -o - | FileCheck %s -// CHECK-NOT: TAG_member +// CHECK: ; [ DW_TAG_class_type ] [B] {{.*}} [decl] class B { public: