[PATCH] Output debug information for structure members only referenced by a pointer or typedef

David Blaikie dblaikie at gmail.com
Wed Jun 19 10:27:36 PDT 2013


On Wed, Jun 19, 2013 at 5:34 AM, Keith Walker <keith.walker at arm.com> wrote:
> This patch addresses an issue introduced by r183296 that means that the
> members of a structure are no longer output in the DWARF debugging
> information if the structure is only referenced by a pointer or typedef
> (reported in PR16214).

Does r184252 address your issue?

What's the particular regression you're trying to fix related to
pointers without typedefs? I'm pretty sure even pre-r183296 a simple
piece of code involving a struct definition and the declaration of a
variable that is a pointer to that type would've only emitted the
declaration of that type. Did you observe different behavior?

> Files:
>   test/CodeGenCXX/debug-info-namespace.cpp
>   test/CodeGenCXX/debug-info.cpp
>   lib/CodeGen/CGDebugInfo.cpp
>
> Index: test/CodeGenCXX/debug-info-namespace.cpp
> ===================================================================
> --- test/CodeGenCXX/debug-info-namespace.cpp    (revision 184291)
> +++ test/CodeGenCXX/debug-info-namespace.cpp    (working copy)
> @@ -57,7 +57,7 @@
>  // CHECK: [[M6]] = metadata !{i32 {{[0-9]*}}, metadata [[FUNC]], metadata
> [[FOO:![0-9]*]], i32 21} ; [ DW_TAG_imported_declaration ]
>  // CHECK: [[FOO]] {{.*}} ; [ DW_TAG_structure_type ] [foo] [line 5, size 0,
> align 0, offset 0] [fwd] [from ]
>  // CHECK: [[M7]] = metadata !{i32 {{[0-9]*}}, metadata [[FUNC]], metadata
> [[BAR:![0-9]*]], i32 22} ; [ DW_TAG_imported_declaration ]
> -// CHECK: [[BAR]] {{.*}} ; [ DW_TAG_structure_type ] [bar] [line 6, {{.*}}]
> [fwd] [from ]
> +// CHECK: [[BAR]] {{.*}} ; [ DW_TAG_structure_type ] [bar] [line 6, {{.*}}]
> [from ]
>  // CHECK: [[M8]] = metadata !{i32 {{[0-9]*}}, metadata [[FUNC]], metadata
> [[F1]], i32 23} ; [ DW_TAG_imported_declaration ]
>  // CHECK: [[M9]] = metadata !{i32 {{[0-9]*}}, metadata [[FUNC]], metadata
> [[I]], i32 24} ; [ DW_TAG_imported_declaration ]
>  // CHECK: [[M10]] = metadata !{i32 {{[0-9]*}}, metadata [[FUNC]], metadata
> [[BAZ:![0-9]*]], i32 25} ; [ DW_TAG_imported_declaration ]
> Index: test/CodeGenCXX/debug-info.cpp
> ===================================================================
> --- test/CodeGenCXX/debug-info.cpp      (revision 184291)
> +++ test/CodeGenCXX/debug-info.cpp      (working copy)
> @@ -102,18 +102,26 @@
>  typedef a at;
>
>  struct b {
> +  int j;
>  };
>
> +struct c;
> +
>  typedef b bt;
> +typedef c ct;
>
>  void func() {
>    at a_inst;
>    bt *b_ptr_inst;
>    const bt *b_cnst_ptr_inst;
> +  ct *c_ptr_inst;
>  }
>
>  // CHECK: metadata [[A_MEM:![0-9]*]], i32 0, null, null} ; [
> DW_TAG_structure_type ] [a]
>  // CHECK: [[A_MEM]] = metadata !{metadata [[A_I:![0-9]*]], metadata
> !{{[0-9]*}}}
>  // CHECK: [[A_I]] = {{.*}} ; [ DW_TAG_member ] [i] {{.*}} [from int]
> -// CHECK: ; [ DW_TAG_structure_type ] [b] {{.*}}[fwd]
> +// CHECK: metadata [[B_MEM:![0-9]*]], i32 0, null, null} ; [
> DW_TAG_structure_type ] [b]
> +// CHECK: [[B_MEM]] = metadata !{metadata [[B_J:![0-9]*]]}
> +// CHECK: [[B_J]] = {{.*}} ; [ DW_TAG_member ] [j] {{.*}} [from int]
> +// CHECK: ; [ DW_TAG_structure_type ] [c] {{.*}}[fwd]
>  }
> Index: lib/CodeGen/CGDebugInfo.cpp
> ===================================================================
> --- lib/CodeGen/CGDebugInfo.cpp (revision 184291)
> +++ lib/CodeGen/CGDebugInfo.cpp (working copy)
> @@ -615,7 +615,8 @@
>                                                       llvm::DIFile Unit) {
>    if (DebugKind > CodeGenOptions::LimitedDebugInfo)
>      return getOrCreateType(PointeeTy, Unit);
> -  return getOrCreateType(PointeeTy, Unit, true);
> +  bool Declaration = isa<RecordType>(PointeeTy);
> +  return getOrCreateType(PointeeTy, Unit, Declaration);

This is not the right fix - we don't want to always emit definitions
for types referenced via pointers or typedefs in all cases.

Limited debug info (r184252 probably addresses your issue when
building with -fno-limit-debug-info) is intended to reduce debug info
by taking steps including emitting only the declaration of types that
are only used in ways that a definition would not be needed.

In your test case there's no use of the concrete type 'b' - only some
pointers to 'b' that are never dereferenced. (the test here is "if a
struct definition were replaced with a declaration, would the code
still compile" - if that condition is met, then the intent is that
Clang emit only a declaration for that type when building with
-flimit-debug-info (which is the default))

Does that make sense?

As for how to fix it - we'd have to look at how to plumb in hooks for
the debug info to be invoked (to request the full definition of a
type) when we visit expressions that require the full definition (eg
in Adrian's r184252 the commented line in the test case that
dereferences the pointer).

>  }
>
>  llvm::DIType CGDebugInfo::CreatePointerLikeType(unsigned Tag,



More information about the cfe-commits mailing list