From: Adrian Prantl Date: Thu, 20 Jun 2013 21:17:24 +0000 (+0000) Subject: Debug Info: Attempt to resolve forward declarations if we are not emitting X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=6bb110292c4e33a6ee2856cf91e0774107aa7d9c;p=clang Debug Info: Attempt to resolve forward declarations if we are not emitting limited debug info. This is another small addendum to r184252. rdar://problem/14101097 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@184473 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/CodeGen/CGDebugInfo.cpp b/lib/CodeGen/CGDebugInfo.cpp index 8240c0846d..f8c814cb94 100644 --- a/lib/CodeGen/CGDebugInfo.cpp +++ b/lib/CodeGen/CGDebugInfo.cpp @@ -1886,6 +1886,22 @@ llvm::DIType CGDebugInfo::getTypeOrNull(QualType Ty) { return llvm::DIType(); } +/// ContainsFwdDecl - True if Ty is either a forward declaration or a +/// derived type of a forward declaration. +static bool ContainsFwdDecl(llvm::DIType Ty) { + // Composite types such as structs inherit from DIDerivedType, so + // check this first and do an early exit. + if (Ty.isForwardDecl()) + return true; + + if (Ty.isDerivedType()) { + llvm::DIDerivedType DTy(Ty); + return ContainsFwdDecl(DTy.getTypeDerivedFrom()); + } + + return false; +} + /// getCompletedTypeOrNull - Get the type from the cache or return null if it /// doesn't exist. llvm::DIType CGDebugInfo::getCompletedTypeOrNull(QualType Ty) { @@ -1904,8 +1920,17 @@ llvm::DIType CGDebugInfo::getCompletedTypeOrNull(QualType Ty) { } // Verify that any cached debug info still exists. - if (V != 0) - return llvm::DIType(cast(V)); + if (V != 0) { + llvm::DIType CachedType(cast(V)); + + // Unless we are limiting debug info, attempt to resolve any + // forward declarations. + if (DebugKind > CodeGenOptions::LimitedDebugInfo && + ContainsFwdDecl(CachedType)) + return llvm::DIType(); + + return CachedType; + } return llvm::DIType(); } diff --git a/test/CodeGen/debug-info-record.c b/test/CodeGen/debug-info-record.c index 55927ca667..546a8b9806 100644 --- a/test/CodeGen/debug-info-record.c +++ b/test/CodeGen/debug-info-record.c @@ -1,5 +1,5 @@ // RUN: %clang_cc1 -triple x86_64-unk-unk -fno-limit-debug-info -o - -emit-llvm -g %s | FileCheck %s -// Check that we emit debug info for a struct even if it is typedef'd before using. +// Check that we emit debug info for a struct even if it is typedef'd. // rdar://problem/14101097 // // FIXME: This should work with -flimit-debug-info, too. diff --git a/test/CodeGen/debug-info-record2.c b/test/CodeGen/debug-info-record2.c new file mode 100644 index 0000000000..3f28296318 --- /dev/null +++ b/test/CodeGen/debug-info-record2.c @@ -0,0 +1,21 @@ +// RUN: %clang_cc1 -triple x86_64-unk-unk -fno-limit-debug-info -o - -emit-llvm -g %s | FileCheck %s +// Check that we emit debug info for a struct even if it is typedef'd before using. +// rdar://problem/14101097 +// +// FIXME: This should work with -flimit-debug-info, too. + +// Make sure this is not a forward declaration. +// CHECK-NOT: [ DW_TAG_structure_type ] [elusive_s] {{.*}} [fwd] +// CHECK: [ DW_TAG_member ] [foo] +// CHECK: [ DW_TAG_member ] [bar] +typedef struct elusive_s* elusive_t; +elusive_t first_use = (void*)0; +struct elusive_s { + int foo; + float bar; +}; + +int baz(void* x) { + elusive_t s = x; + return s->foo; +}