r274628 - Include debug info for nested structs and classes

David Blaikie via cfe-commits cfe-commits at lists.llvm.org
Fri Jul 8 11:58:13 PDT 2016


On Thu, Jul 7, 2016 at 4:22 PM, Adrian McCarthy <amccarth at google.com> wrote:

> This patch was reverted because it breaks a test on the buildbots (that
> I've been unable to reproduce locally), so that's why you didn't seen
> anything.  I'll try again to land the patch once I can fix and verify that
> test.
>
> This patch is one part of the change.  The other part is
> http://reviews.llvm.org/D21939, which ensures this extra info is carried
> through for CodeView debug info.
>
> I'm not familiar with DWARF type units (but am currently reading about
> them).  I don't immediately see how this change would affect the
> calculation of the type signature.
>

Actually we build the signature based on the mangled name of the type - not
the DIEs that make up the type unit. So we want to ensure that the type
unit for the same type comes out the same in any TU.

Since we weren't including unreferenced nested types, what we would do is
not include nested types in the member list - that way when we build the
type we don't include those nested types (we use the same technique for
implicit special members and member function templates). Those elements end
up in the other part of the DWARF that references the type unit - the same
way declarations for defined members appear there (since DWARF type units
don't provide a way to reference anything other than the type - so...
anyway, long story).


> The intent is to ensure that there is a type record for Bar in code like
> this:
>
> struct Foo {
>   struct Bar {};
> };
>
> Without this change, Bar is omitted from the debug info metadata.
>

Do you know how this will work with this case:

struct Foo {
  struct Bar;
};

Where Bar is defined and used in one TU but not defined in the other? I
don't think we have the ability to emit both a declaration and a definition
of a type in the same translation unit, which would make it difficult to
describe Foo the same in both translation units (since in the TU without
Bar's definition Foo would contain a declaration, and in the TU with Bar's
definition we'd need to emit the definition and perhaps have no way
(currently) to also emit the declaration)

Also, from a debug info size perspective, it'd be unfortunate if we
required all nested types to be fully defined/emitted (if we can support
the decl/def situation above, perhaps we could make even inline nested type
definitions appear as separate decl/def to keep the option to omit the
nested type definition and keep debug info size small-ish (it'd still grow
a bit by adding the declarations even when the type's unreferenced - so I'd
sort of like to keep that for DWARF if reasonable))

Also: if consistency of type definition is important for CV: What happens
with implicit special members and member function templates?


>
>
> On Thu, Jul 7, 2016 at 4:03 PM, David Blaikie <dblaikie at gmail.com> wrote:
>
>> This may cause problems for DWARF type unit consistency...
>>
>> Under what conditions do nested types appear in the member list? (my
>> simple test case on a fresh clang didn't seem to produce anything about the
>> nested type: struct outer { struct inner { int i; }; int j; }; outer o; )
>>
>> On Wed, Jul 6, 2016 at 7:46 AM, Adrian McCarthy via cfe-commits <
>> cfe-commits at lists.llvm.org> wrote:
>>
>>> Author: amccarth
>>> Date: Wed Jul  6 09:46:42 2016
>>> New Revision: 274628
>>>
>>> URL: http://llvm.org/viewvc/llvm-project?rev=274628&view=rev
>>> Log:
>>> Include debug info for nested structs and classes
>>>
>>> This includes nested types in the member list, even if there are no
>>> members of that type. Note that structs and classes have themselves as an
>>> "implicit struct" as the first member, so we skip implicit ones.
>>>
>>> Differential Revision: http://reviews.llvm.org/D21705
>>>
>>> Modified:
>>>     cfe/trunk/lib/CodeGen/CGDebugInfo.cpp
>>>     cfe/trunk/lib/CodeGen/CGDebugInfo.h
>>>     cfe/trunk/test/CodeGenCXX/debug-info-dup-fwd-decl.cpp
>>>     cfe/trunk/test/CodeGenCXX/debug-info-indirect-field-decl.cpp
>>>     cfe/trunk/test/CodeGenCXX/debug-info-ms-abi.cpp
>>>
>>> Modified: cfe/trunk/lib/CodeGen/CGDebugInfo.cpp
>>> URL:
>>> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGDebugInfo.cpp?rev=274628&r1=274627&r2=274628&view=diff
>>>
>>> ==============================================================================
>>> --- cfe/trunk/lib/CodeGen/CGDebugInfo.cpp (original)
>>> +++ cfe/trunk/lib/CodeGen/CGDebugInfo.cpp Wed Jul  6 09:46:42 2016
>>> @@ -1095,6 +1095,13 @@ void CGDebugInfo::CollectRecordNormalFie
>>>    elements.push_back(FieldType);
>>>  }
>>>
>>> +void CGDebugInfo::CollectRecordNestedRecord(
>>> +    const RecordDecl *RD, SmallVectorImpl<llvm::Metadata *> &elements) {
>>> +  QualType Ty = CGM.getContext().getTypeDeclType(RD);
>>> +  llvm::DIType *nestedType = getOrCreateType(Ty, getOrCreateMainFile());
>>> +  elements.push_back(nestedType);
>>> +}
>>> +
>>>  void CGDebugInfo::CollectRecordFields(
>>>      const RecordDecl *record, llvm::DIFile *tunit,
>>>      SmallVectorImpl<llvm::Metadata *> &elements,
>>> @@ -1131,6 +1138,9 @@ void CGDebugInfo::CollectRecordFields(
>>>
>>>          // Bump field number for next field.
>>>          ++fieldNo;
>>> +      } else if (const auto *nestedRec = dyn_cast<CXXRecordDecl>(I)) {
>>> +        if (!nestedRec->isImplicit() && nestedRec->getDeclContext() ==
>>> record)
>>> +          CollectRecordNestedRecord(nestedRec, elements);
>>>        }
>>>    }
>>>  }
>>> @@ -3633,8 +3643,8 @@ void CGDebugInfo::EmitUsingDirective(con
>>>    if (CGM.getCodeGenOpts().getDebugInfo() <
>>> codegenoptions::LimitedDebugInfo)
>>>      return;
>>>    const NamespaceDecl *NSDecl = UD.getNominatedNamespace();
>>> -  if (!NSDecl->isAnonymousNamespace() ||
>>> -      CGM.getCodeGenOpts().DebugExplicitImport) {
>>> +  if (!NSDecl->isAnonymousNamespace() ||
>>> +      CGM.getCodeGenOpts().DebugExplicitImport) {
>>>      DBuilder.createImportedModule(
>>>          getCurrentContextDescriptor(cast<Decl>(UD.getDeclContext())),
>>>          getOrCreateNameSpace(NSDecl),
>>>
>>> Modified: cfe/trunk/lib/CodeGen/CGDebugInfo.h
>>> URL:
>>> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGDebugInfo.h?rev=274628&r1=274627&r2=274628&view=diff
>>>
>>> ==============================================================================
>>> --- cfe/trunk/lib/CodeGen/CGDebugInfo.h (original)
>>> +++ cfe/trunk/lib/CodeGen/CGDebugInfo.h Wed Jul  6 09:46:42 2016
>>> @@ -254,6 +254,8 @@ class CGDebugInfo {
>>>                                  llvm::DIFile *F,
>>>                                  SmallVectorImpl<llvm::Metadata *> &E,
>>>                                  llvm::DIType *RecordTy, const
>>> RecordDecl *RD);
>>> +  void CollectRecordNestedRecord(const RecordDecl *RD,
>>> +                                 SmallVectorImpl<llvm::Metadata *> &E);
>>>    void CollectRecordFields(const RecordDecl *Decl, llvm::DIFile *F,
>>>                             SmallVectorImpl<llvm::Metadata *> &E,
>>>                             llvm::DICompositeType *RecordTy);
>>>
>>> Modified: cfe/trunk/test/CodeGenCXX/debug-info-dup-fwd-decl.cpp
>>> URL:
>>> http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/debug-info-dup-fwd-decl.cpp?rev=274628&r1=274627&r2=274628&view=diff
>>>
>>> ==============================================================================
>>> --- cfe/trunk/test/CodeGenCXX/debug-info-dup-fwd-decl.cpp (original)
>>> +++ cfe/trunk/test/CodeGenCXX/debug-info-dup-fwd-decl.cpp Wed Jul  6
>>> 09:46:42 2016
>>> @@ -19,6 +19,6 @@ protected:
>>>
>>>  Test t;
>>>
>>> -// CHECK: !DIDerivedType(tag: DW_TAG_pointer_type
>>>  // CHECK: !DICompositeType(tag: DW_TAG_structure_type, name: "data"
>>> +// CHECK: !DIDerivedType(tag: DW_TAG_pointer_type
>>>  // CHECK-NOT: !DICompositeType(tag: DW_TAG_structure_type, name: "data"
>>>
>>> Modified: cfe/trunk/test/CodeGenCXX/debug-info-indirect-field-decl.cpp
>>> URL:
>>> http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/debug-info-indirect-field-decl.cpp?rev=274628&r1=274627&r2=274628&view=diff
>>>
>>> ==============================================================================
>>> --- cfe/trunk/test/CodeGenCXX/debug-info-indirect-field-decl.cpp
>>> (original)
>>> +++ cfe/trunk/test/CodeGenCXX/debug-info-indirect-field-decl.cpp Wed
>>> Jul  6 09:46:42 2016
>>> @@ -8,18 +8,18 @@ template <class T, int T::*ptr> class Fo
>>>  struct Bar {
>>>    int i1;
>>>    // CHECK: ![[INT:[0-9]+]] = !DIBasicType(name: "int"
>>> -  // CHECK: !DIDerivedType(tag: DW_TAG_member, scope:
>>> -  // CHECK-SAME:           line: [[@LINE+4]]
>>> -  // CHECK-SAME:           baseType: ![[UNION:[0-9]+]]
>>> -  // CHECK-SAME:           size: 32, align: 32, offset: 32
>>> -  // CHECK: ![[UNION]] = distinct !DICompositeType(tag:
>>> DW_TAG_union_type,{{.*}} identifier: "_ZTSN3BarUt_E")
>>> +  // CHECK: ![[UNION:[0-9]+]] = distinct !DICompositeType(tag:
>>> DW_TAG_union_type,{{.*}} identifier: "_ZTSN3BarUt_E")
>>>    union {
>>>      // CHECK: !DIDerivedType(tag: DW_TAG_member, name: "i2",
>>> -    // CHECK-SAME:           line: [[@LINE+5]]
>>> +    // CHECK-SAME:           line: [[@LINE+9]]
>>>      // CHECK-SAME:           baseType: ![[INT]]
>>>      // CHECK-SAME:           size: 32, align: 32
>>>      // CHECK-NOT:            offset:
>>>      // CHECK-SAME:           ){{$}}
>>> +    // CHECK: !DIDerivedType(tag: DW_TAG_member, scope:
>>> +    // CHECK-SAME:           line: [[@LINE-8]]
>>> +    // CHECK-SAME:           baseType: ![[UNION]]
>>> +    // CHECK-SAME:           size: 32, align: 32, offset: 32
>>>      int i2;
>>>    };
>>>  };
>>>
>>> Modified: cfe/trunk/test/CodeGenCXX/debug-info-ms-abi.cpp
>>> URL:
>>> http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/debug-info-ms-abi.cpp?rev=274628&r1=274627&r2=274628&view=diff
>>>
>>> ==============================================================================
>>> --- cfe/trunk/test/CodeGenCXX/debug-info-ms-abi.cpp (original)
>>> +++ cfe/trunk/test/CodeGenCXX/debug-info-ms-abi.cpp Wed Jul  6 09:46:42
>>> 2016
>>> @@ -14,6 +14,9 @@ Foo::Nested n;
>>>  // CHECK: ![[Foo:[^ ]*]] = distinct !DICompositeType(tag:
>>> DW_TAG_structure_type, name: "Foo",
>>>  // CHECK-SAME: identifier: ".?AUFoo@@"
>>>
>>> +// CHECK: distinct !DICompositeType(tag: DW_TAG_structure_type, name:
>>> "Nested",
>>> +// CHECK-SAME: identifier: ".?AUNested at Foo@@"
>>> +
>>>  // CHECK: !DISubprogram(name: "f",
>>>  // CHECK-SAME: containingType: ![[Foo]], virtuality:
>>> DW_VIRTUALITY_virtual, virtualIndex: 0,
>>>  // CHECK-SAME: flags: DIFlagPrototyped | DIFlagIntroducedVirtual,
>>> @@ -25,6 +28,3 @@ Foo::Nested n;
>>>  // CHECK: !DISubprogram(name: "h",
>>>  // CHECK-SAME: containingType: ![[Foo]], virtuality:
>>> DW_VIRTUALITY_virtual, virtualIndex: 2,
>>>  // CHECK-SAME: flags: DIFlagPrototyped | DIFlagIntroducedVirtual,
>>> -
>>> -// CHECK: distinct !DICompositeType(tag: DW_TAG_structure_type, name:
>>> "Nested",
>>> -// CHECK-SAME: identifier: ".?AUNested at Foo@@"
>>>
>>>
>>> _______________________________________________
>>> cfe-commits mailing list
>>> cfe-commits at lists.llvm.org
>>> http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
>>>
>>
>>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20160708/cf3ad37e/attachment-0001.html>


More information about the cfe-commits mailing list