r188640 - DebugInfo: Avoid duplicating types that may be created during the process of creating their context
David Blaikie
dblaikie at gmail.com
Sun Aug 18 10:36:19 PDT 2013
Author: dblaikie
Date: Sun Aug 18 12:36:19 2013
New Revision: 188640
URL: http://llvm.org/viewvc/llvm-project?rev=188640&view=rev
Log:
DebugInfo: Avoid duplicating types that may be created during the process of creating their context
A partner to r188639, this is a somewhat heavy-handed fix to the general
issue, since even after that prior change the issue does still
unavoidably arise with template parameters (see test case).
There are other ways we could consider addressing this (see FIXME).
Modified:
cfe/trunk/lib/CodeGen/CGDebugInfo.cpp
cfe/trunk/test/CodeGenCXX/debug-info-template-member.cpp
Modified: cfe/trunk/lib/CodeGen/CGDebugInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGDebugInfo.cpp?rev=188640&r1=188639&r2=188640&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGDebugInfo.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGDebugInfo.cpp Sun Aug 18 12:36:19 2013
@@ -2183,6 +2183,19 @@ llvm::DIType CGDebugInfo::CreateLimitedT
else
RDContext = getContextDescriptor(cast<Decl>(RD->getDeclContext()));
+ // If we ended up creating the type during the context chain construction,
+ // just return that.
+ // FIXME: this could be dealt with better if the type was recorded as
+ // completed before we started this (see the CompletedTypeCache usage in
+ // CGDebugInfo::CreateTypeDefinition(const RecordType*) - that would need to
+ // be pushed to before context creation, but after it was known to be
+ // destined for completion (might still have an issue if this caller only
+ // required a declaration but the context construction ended up creating a
+ // definition)
+ if (llvm::DIType T = getTypeOrNull(CGM.getContext().getRecordType(RD)))
+ if (!T.isForwardDecl() || !RD->getDefinition())
+ return T;
+
// If this is just a forward declaration, construct an appropriately
// marked node and just return it.
if (!RD->getDefinition())
Modified: cfe/trunk/test/CodeGenCXX/debug-info-template-member.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/debug-info-template-member.cpp?rev=188640&r1=188639&r2=188640&view=diff
==============================================================================
--- cfe/trunk/test/CodeGenCXX/debug-info-template-member.cpp (original)
+++ cfe/trunk/test/CodeGenCXX/debug-info-template-member.cpp Sun Aug 18 12:36:19 2013
@@ -17,3 +17,31 @@ inline int add3(int x) {
// CHECK: metadata [[C_MEM:![0-9]*]], i32 0, null, null} ; [ DW_TAG_structure_type ] [MyClass]
// CHECK: [[C_MEM]] = metadata !{metadata [[C_TEMP:![0-9]*]]}
// CHECK: [[C_TEMP]] = {{.*}} ; [ DW_TAG_subprogram ] [line 4] [add<2>]
+
+template<typename T>
+struct outer {
+ struct inner {
+ int i;
+ };
+};
+
+struct foo {
+ void func(outer<foo>::inner);
+};
+
+inline void func() {
+ // require 'foo' to be complete before the emission of 'inner' so that, when
+ // constructing the context chain for 'x' we emit the full definition of
+ // 'foo', which requires the definition of 'inner' again
+ foo f;
+}
+
+outer<foo>::inner x;
+
+// CHECK: metadata [[OUTER_FOO_INNER:![0-9]*]], i32 {{[0-9]*}}, i32 {{[0-9]*}}, %"struct.outer<foo>::inner"* @x, {{.*}} ; [ DW_TAG_variable ] [x]
+// CHECK: [[OUTER_FOO_INNER]] = {{.*}} ; [ DW_TAG_structure_type ] [inner]
+// CHECK: [[FOO_MEM:![0-9]*]], i32 0, null, null} ; [ DW_TAG_structure_type ] [foo]
+// CHECK: [[FOO_MEM]] = metadata !{metadata [[FOO_FUNC:![0-9]*]]}
+// CHECK: [[FOO_FUNC]] = {{.*}}, metadata !"_ZN3foo4funcEN5outerIS_E5innerE", i32 {{[0-9]*}}, metadata [[FOO_FUNC_TYPE:![0-9]*]], {{.*}} ; [ DW_TAG_subprogram ] {{.*}} [func]
+// CHECK: [[FOO_FUNC_TYPE]] = {{.*}}, metadata [[FOO_FUNC_PARAMS:![0-9]*]], i32 0, i32 0} ; [ DW_TAG_subroutine_type ]
+// CHECK: [[FOO_FUNC_PARAMS]] = metadata !{null, metadata !{{[0-9]*}}, metadata [[OUTER_FOO_INNER]]}
More information about the cfe-commits
mailing list