Skip to content
Open
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
55 changes: 55 additions & 0 deletions clang/lib/CodeGen/CGDebugInfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1235,6 +1235,7 @@ CGDebugInfo::getOrCreateRecordFwdDecl(const RecordType *Ty,
// Don't include a linkage name in line tables only.
if (CGM.getCodeGenOpts().hasReducedDebugInfo())
Identifier = getTypeIdentifier(Ty, CGM, TheCU);
Ctx = PickCompositeTypeScope(Ctx, Identifier);
llvm::DICompositeType *RetTy = DBuilder.createReplaceableCompositeType(
getTagForRecord(RD), RDName, Ctx, DefUnit, Line, 0, Size, Align, Flags,
Identifier);
Expand Down Expand Up @@ -3534,6 +3535,7 @@ llvm::DIType *CGDebugInfo::CreateEnumType(const EnumType *Ty) {
// FwdDecl with the second and then replace the second with
// complete type.
llvm::DIScope *EDContext = getDeclContextDescriptor(ED);
EDContext = PickCompositeTypeScope(EDContext, Identifier);
llvm::DIFile *DefUnit = getOrCreateFile(ED->getLocation());
llvm::TempDIScope TmpContext(DBuilder.createReplaceableCompositeType(
llvm::dwarf::DW_TAG_enumeration_type, "", TheCU, DefUnit, 0));
Expand Down Expand Up @@ -3901,6 +3903,58 @@ CGDebugInfo::getOrCreateLimitedType(const RecordType *Ty) {
return Res;
}

llvm::DIScope *
CGDebugInfo::PickCompositeTypeScope(llvm::DIScope *S, StringRef Identifier) {
using llvm::DISubprogram;

// Only adjust the scope for composite types placed into functions.
if (!isa<DISubprogram>(S))
return S;

// We must adjust the scope if the ODR-name of the type is set.
if (Identifier.empty())
return S;

// This type has an ODR-name, and might be de-duplicated during LTO. It needs
// to be placed in the unique declaration of the function, not a (potentially
// duplicated) definition.
DISubprogram *SP = cast<DISubprogram>(S);
if (DISubprogram *Decl = SP->getDeclaration())
return Decl;

// There is no declaration -- we must produce one and retrofit it to the
// existing definition. Assume that we can just harvest the existing
// information, clear the definition flag and set as decl.
DISubprogram::DISPFlags SPFlags = SP->getSPFlags();
SPFlags &= ~DISubprogram::SPFlagDefinition;

llvm::DINode::DIFlags Flags = SP->getFlags();
Flags &= ~llvm::DINode::FlagAllCallsDescribed;

#ifdef EXPENSIVE_CHECKS
// If we're looking to be really rigorous and avoid a hard-to-debug mishap,
// make sure that there aren't any function definitions in the scope chain.
llvm::DIScope *ToCheck = SP->getScope();
do {
// We should terminate at a DIFile rather than a DICompileUnit -- we're
// not fully unique across LTO otherwise.
assert(!isa<llvm::DICompileUnit>(ToCheck));
if (auto *DISP = dyn_cast<DISubprogram>(ToCheck))
assert(!(DISP->getSPFlags() & DISubprogram::SPFlagDefinition));
ToCheck = ToCheck->getScope();
} while (ToCheck);
#endif

DISubprogram *DeclSP = DBuilder.createFunction(
SP->getScope(), SP->getName(), SP->getLinkageName(), SP->getFile(),
SP->getLine(), SP->getType(), SP->getScopeLine(),
Flags, SPFlags, SP->getTemplateParams(), nullptr, nullptr,
SP->getAnnotations());

SP->replaceDeclaration(DeclSP);
return DeclSP;
}

// TODO: Currently used for context chains when limiting debug info.
llvm::DICompositeType *CGDebugInfo::CreateLimitedType(const RecordType *Ty) {
RecordDecl *RD = Ty->getDecl();
Expand Down Expand Up @@ -3938,6 +3992,7 @@ llvm::DICompositeType *CGDebugInfo::CreateLimitedType(const RecordType *Ty) {
auto Align = getTypeAlignIfRequired(Ty, CGM.getContext());

SmallString<256> Identifier = getTypeIdentifier(Ty, CGM, TheCU);
RDContext = PickCompositeTypeScope(RDContext, Identifier);

// Explicitly record the calling convention and export symbols for C++
// records.
Expand Down
2 changes: 2 additions & 0 deletions clang/lib/CodeGen/CGDebugInfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -486,6 +486,8 @@ class CGDebugInfo {
void EmitFunctionDecl(GlobalDecl GD, SourceLocation Loc,
QualType FnType, llvm::Function *Fn = nullptr);

llvm::DIScope *PickCompositeTypeScope(llvm::DIScope *S, StringRef Identifier);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you add a doxygen comment that explains the purpose of this function?


/// Emit debug info for an extern function being called.
/// This is needed for call site debug info.
void EmitFuncDeclForCallSite(llvm::CallBase *CallOrInvoke,
Expand Down
16 changes: 8 additions & 8 deletions clang/test/CodeGen/debug-info-codeview-unnamed.c
Original file line number Diff line number Diff line change
Expand Up @@ -8,23 +8,23 @@ int main(int argc, char* argv[], char* arge[]) {
//
struct { int bar; } one = {42};
//
// LINUX: !{{[0-9]+}} = !DILocalVariable(name: "one"
// LINUX-SAME: type: [[TYPE_OF_ONE:![0-9]+]]
// LINUX-SAME: )
// LINUX: [[TYPE_OF_ONE]] = distinct !DICompositeType(
// LINUX: [[TYPE_OF_ONE:![0-9]+]] = distinct !DICompositeType(
// LINUX-SAME: tag: DW_TAG_structure_type
// LINUX-NOT: name:
// LINUX-NOT: identifier:
// LINUX-SAME: )
// LINUX: !{{[0-9]+}} = !DILocalVariable(name: "one"
// LINUX-SAME: type: [[TYPE_OF_ONE]]
// LINUX-SAME: )
//
// MSVC: !{{[0-9]+}} = !DILocalVariable(name: "one"
// MSVC-SAME: type: [[TYPE_OF_ONE:![0-9]+]]
// MSVC-SAME: )
// MSVC: [[TYPE_OF_ONE]] = distinct !DICompositeType
// MSVC: [[TYPE_OF_ONE:![0-9]+]] = distinct !DICompositeType
// MSVC-SAME: tag: DW_TAG_structure_type
// MSVC-NOT: name:
// MSVC-NOT: identifier:
// MSVC-SAME: )
// MSVC: !{{[0-9]+}} = !DILocalVariable(name: "one"
// MSVC-SAME: type: [[TYPE_OF_ONE]]
// MSVC-SAME: )

return 0;
}
16 changes: 9 additions & 7 deletions clang/test/CodeGen/debug-info-unused-types.c
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,15 @@ void quux(void) {
// CHECK: !DICompileUnit{{.+}}retainedTypes: [[RETTYPES:![0-9]+]]
// CHECK: [[TYPE0:![0-9]+]] = !DICompositeType(tag: DW_TAG_enumeration_type, name: "bar"
// CHECK: [[TYPE1:![0-9]+]] = !DIEnumerator(name: "BAR"
// CHECK: [[TYPE2:![0-9]+]] = !DICompositeType(tag: DW_TAG_enumeration_type, name: "z"
// CHECK: [[TYPE3:![0-9]+]] = !DIEnumerator(name: "Z"
// CHECK: [[RETTYPES]] = !{[[TYPE4:![0-9]+]], [[TYPE5:![0-9]+]], [[TYPE0]], [[TYPE6:![0-9]+]], {{![0-9]+}}, [[TYPE7:![0-9]+]], [[TYPE2]], [[TYPE8:![0-9]+]]}
// CHECK: [[TYPE4]] = !DIDerivedType(tag: DW_TAG_typedef, name: "my_int"
// CHECK: [[TYPE5]] = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "foo"
// CHECK: [[TYPE6]] = distinct !DICompositeType(tag: DW_TAG_union_type, name: "baz"
// CHECK: [[TYPE7]] = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "y"
// CHECK: [[RETTYPES]] = !{[[TYPE2:![0-9]+]], [[TYPE3:![0-9]+]], [[TYPE0]], [[TYPE4:![0-9]+]], {{![0-9]+}}}
// CHECK: [[TYPE2]] = !DIDerivedType(tag: DW_TAG_typedef, name: "my_int"
// CHECK: [[TYPE3]] = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "foo"
// CHECK: [[TYPE4]] = distinct !DICompositeType(tag: DW_TAG_union_type, name: "baz"
// CHECK: [[SP:![0-9]+]] = distinct !DISubprogram(name: "quux", {{.*}}, retainedNodes: [[SPRETNODES:![0-9]+]]
// CHECK: [[SPRETNODES]] = !{[[TYPE5:![0-9]+]], [[TYPE6:![0-9]+]], [[TYPE8:![0-9]+]]}
// CHECK: [[TYPE5]] = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "y"
// CHECK: [[TYPE6]] = !DICompositeType(tag: DW_TAG_enumeration_type, name: "z"
// CHECK: [[TYPE7:![0-9]+]] = !DIEnumerator(name: "Z"
// CHECK: [[TYPE8]] = distinct !DICompositeType(tag: DW_TAG_union_type, name: "w"

// Check that debug info is not emitted for the typedef, struct, enum, and
Expand Down
14 changes: 8 additions & 6 deletions clang/test/CodeGen/debug-info-unused-types.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,14 @@ void quux() {
// CHECK: !DICompileUnit{{.+}}retainedTypes: [[RETTYPES:![0-9]+]]
// CHECK: [[TYPE0:![0-9]+]] = !DICompositeType(tag: DW_TAG_enumeration_type, name: "baz"
// CHECK: [[TYPE1:![0-9]+]] = !DIEnumerator(name: "BAZ"
// CHECK: [[TYPE2:![0-9]+]] = !DICompositeType(tag: DW_TAG_enumeration_type, name: "z"
// CHECK: [[TYPE3:![0-9]+]] = !DIEnumerator(name: "Z"
// CHECK: [[RETTYPES]] = !{[[TYPE4:![0-9]+]], [[TYPE5:![0-9]+]], [[TYPE0]], {{![0-9]+}}, [[TYPE6:![0-9]+]], [[TYPE2]]}
// CHECK: [[TYPE4]] = !DIDerivedType(tag: DW_TAG_typedef, name: "foo"
// CHECK: [[TYPE5]] = distinct !DICompositeType(tag: DW_TAG_class_type, name: "bar"
// CHECK: [[TYPE6]] = distinct !DICompositeType(tag: DW_TAG_class_type, name: "y"
// CHECK: [[RETTYPES]] = !{[[TYPE2:![0-9]+]], [[TYPE3:![0-9]+]], [[TYPE0]], {{![0-9]+}}}
// CHECK: [[TYPE2]] = !DIDerivedType(tag: DW_TAG_typedef, name: "foo"
// CHECK: [[TYPE3]] = distinct !DICompositeType(tag: DW_TAG_class_type, name: "bar"
// CHECK: [[SP:![0-9]+]] = distinct !DISubprogram(name: "quux", {{.*}}, retainedNodes: [[SPRETNODES:![0-9]+]]
// CHECK: [[SPRETNODES]] = !{[[TYPE4:![0-9]+]], [[TYPE5:![0-9]+]]}
// CHECK: [[TYPE4]] = distinct !DICompositeType(tag: DW_TAG_class_type, name: "y", scope: [[SP]]
// CHECK: [[TYPE5]] = !DICompositeType(tag: DW_TAG_enumeration_type, name: "z", scope: [[SP]]
// CHECK: [[TYPE6:![0-9]+]] = !DIEnumerator(name: "Z"

// NODBG-NOT: !DI{{CompositeType|Enumerator|DerivedType}}

Expand Down
2 changes: 1 addition & 1 deletion clang/test/CodeGenCXX/debug-info-access.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,9 @@ class B : public A {
static int public_static;

protected:
// CHECK-DAG: !DIDerivedType(tag: DW_TAG_typedef, name: "prot_using",{{.*}} line: [[@LINE+3]],{{.*}} flags: DIFlagProtected)
// CHECK-DAG: !DIDerivedType(tag: DW_TAG_typedef, name: "prot_typedef",{{.*}} line: [[@LINE+1]],{{.*}} flags: DIFlagProtected)
typedef int prot_typedef;
// CHECK-DAG: !DIDerivedType(tag: DW_TAG_typedef, name: "prot_using",{{.*}} line: [[@LINE+1]],{{.*}} flags: DIFlagProtected)
using prot_using = prot_typedef;
prot_using prot_member;

Expand Down
12 changes: 6 additions & 6 deletions clang/test/CodeGenCXX/debug-info-anon-union-vars.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -51,13 +51,13 @@ void instantiate(int x) {
// CHECK: !DIGlobalVariable(name: "b",{{.*}} file: [[FILE]], line: 6,{{.*}} isLocal: true, isDefinition: true
// CHECK: !DIGlobalVariable(name: "result", {{.*}} isLocal: false, isDefinition: true
// CHECK: !DIGlobalVariable(name: "value", {{.*}} isLocal: false, isDefinition: true
// CHECK: !DILocalVariable(name: "i", {{.*}}, flags: DIFlagArtificial
// CHECK: !DILocalVariable(name: "c", {{.*}}, flags: DIFlagArtificial
// CHECK: !DILocalVariable(
// CHECK-NOT: name:
// CHECK: type: ![[UNION:[0-9]+]]
// CHECK: ![[UNION]] = distinct !DICompositeType(tag: DW_TAG_union_type,
// CHECK: ![[UNION:[0-9]+]] = distinct !DICompositeType(tag: DW_TAG_union_type,
// CHECK-NOT: name:
// CHECK: elements
// CHECK: !DIDerivedType(tag: DW_TAG_member, name: "i", scope: ![[UNION]],
// CHECK: !DIDerivedType(tag: DW_TAG_member, name: "c", scope: ![[UNION]],
// CHECK: !DILocalVariable(name: "i", {{.*}}, flags: DIFlagArtificial
// CHECK: !DILocalVariable(name: "c", {{.*}}, flags: DIFlagArtificial
// CHECK: !DILocalVariable(
// CHECK-NOT: name:
// CHECK: type: ![[UNION]]
63 changes: 36 additions & 27 deletions clang/test/CodeGenCXX/debug-info-codeview-unnamed.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,31 +3,54 @@

int main(int argc, char* argv[], char* arge[]) {
//
// LINUX: [[TYPE_OF_ONE:![0-9]+]] = distinct !DICompositeType(
// LINUX-SAME: tag: DW_TAG_structure_type
// LINUX-NOT: name:
// LINUX-NOT: identifier:
// LINUX-SAME: )

//
// LINUX: [[TYPE_OF_TWO:![0-9]+]] = distinct !DICompositeType(
// LINUX-SAME: tag: DW_TAG_structure_type
// LINUX-NOT: name:
// LINUX-NOT: identifier:
// LINUX-SAME: )
//

//
// LINUX: [[TYPE_OF_THREE:![0-9]+]] = distinct !DICompositeType(
// LINUX-SAME: tag: DW_TAG_structure_type
// LINUX-SAME: name: "named"
// LINUX-NOT: identifier:
// LINUX-SAME: )

//
// LINUX: [[TYPE_OF_FOUR:![0-9]+]] = distinct !DICompositeType(
// LINUX-SAME: tag: DW_TAG_class_type
// LINUX-NOT: name:
// LINUX-NOT: identifier:
// LINUX-SAME: )

// In CodeView, the LF_MFUNCTION entry for "bar()" refers to the forward
// reference of the unnamed struct. Visual Studio requires a unique
// identifier to match the LF_STRUCTURE forward reference to the definition.
//
struct { void bar() {} } one;
//
// LINUX: !{{[0-9]+}} = !DILocalVariable(name: "one"
// LINUX-SAME: type: [[TYPE_OF_ONE:![0-9]+]]
// LINUX-SAME: )
// LINUX: [[TYPE_OF_ONE]] = distinct !DICompositeType(
// LINUX-SAME: tag: DW_TAG_structure_type
// LINUX-NOT: name:
// LINUX-NOT: identifier:
// LINUX-SAME: type: [[TYPE_OF_ONE]]
// LINUX-SAME: )
//
// MSVC: !{{[0-9]+}} = !DILocalVariable(name: "one"
// MSVC-SAME: type: [[TYPE_OF_ONE:![0-9]+]]
// MSVC-SAME: )
//
// MSVC: [[TYPE_OF_ONE]] = distinct !DICompositeType
// MSVC-SAME: tag: DW_TAG_structure_type
// MSVC-SAME: name: "<unnamed-type-one>"
// MSVC-SAME: identifier: ".?AU<unnamed-type-one>@?1??main@@9@"
// MSVC-SAME: )


// In CodeView, the LF_POINTER entry for "ptr2unnamed" refers to the forward
// reference of the unnamed struct. Visual Studio requires a unique
// identifier to match the LF_STRUCTURE forward reference to the definition.
Expand All @@ -36,49 +59,39 @@ int main(int argc, char* argv[], char* arge[]) {
int decltype(two)::*ptr2unnamed = &decltype(two)::bar;
//
// LINUX: !{{[0-9]+}} = !DILocalVariable(name: "two"
// LINUX-SAME: type: [[TYPE_OF_TWO:![0-9]+]]
// LINUX-SAME: )
// LINUX: [[TYPE_OF_TWO]] = distinct !DICompositeType(
// LINUX-SAME: tag: DW_TAG_structure_type
// LINUX-NOT: name:
// LINUX-NOT: identifier:
// LINUX-SAME: type: [[TYPE_OF_TWO]]
// LINUX-SAME: )
//
// MSVC: !{{[0-9]+}} = !DILocalVariable(name: "two"
// MSVC-SAME: type: [[TYPE_OF_TWO:![0-9]+]]
// MSVC-SAME: )
//
// MSVC: [[TYPE_OF_TWO]] = distinct !DICompositeType
// MSVC-SAME: tag: DW_TAG_structure_type
// MSVC-SAME: name: "<unnamed-type-two>"
// MSVC-SAME: identifier: ".?AU<unnamed-type-two>@?2??main@@9@"
// MSVC-SAME: )


// In DWARF, named structures which are not externally visibile do not
// require an identifier. In CodeView, named structures are given an
// identifier.
//
struct named { int bar; int named::* p2mem; } three = { 42, &named::bar };
//
// LINUX: !{{[0-9]+}} = !DILocalVariable(name: "three"
// LINUX-SAME: type: [[TYPE_OF_THREE:![0-9]+]]
// LINUX-SAME: )
// LINUX: [[TYPE_OF_THREE]] = distinct !DICompositeType(
// LINUX-SAME: tag: DW_TAG_structure_type
// LINUX-SAME: name: "named"
// LINUX-NOT: identifier:
// LINUX-SAME: type: [[TYPE_OF_THREE]]
// LINUX-SAME: )
//
// MSVC: !{{[0-9]+}} = !DILocalVariable(name: "three"
// MSVC-SAME: type: [[TYPE_OF_THREE:![0-9]+]]
// MSVC-SAME: )
//
// MSVC: [[TYPE_OF_THREE]] = distinct !DICompositeType
// MSVC-SAME: tag: DW_TAG_structure_type
// MSVC-SAME: name: "named"
// MSVC-SAME: identifier: ".?AUnamed@?1??main@@9@"
// MSVC-SAME: )


// In CodeView, the LF_MFUNCTION entry for the lambda "operator()" routine
// refers to the forward reference of the unnamed LF_CLASS for the lambda.
// Visual Studio requires a unique identifier to match the forward reference
Expand All @@ -87,17 +100,13 @@ int main(int argc, char* argv[], char* arge[]) {
auto four = [argc](int i) -> int { return argc == i ? 1 : 0; };
//
// LINUX: !{{[0-9]+}} = !DILocalVariable(name: "four"
// LINUX-SAME: type: [[TYPE_OF_FOUR:![0-9]+]]
// LINUX-SAME: )
// LINUX: [[TYPE_OF_FOUR]] = distinct !DICompositeType(
// LINUX-SAME: tag: DW_TAG_class_type
// LINUX-NOT: name:
// LINUX-NOT: identifier:
// LINUX-SAME: type: [[TYPE_OF_FOUR]]
// LINUX-SAME: )
//
// MSVC: !{{[0-9]+}} = !DILocalVariable(name: "four"
// MSVC-SAME: type: [[TYPE_OF_FOUR:![0-9]+]]
// MSVC-SAME: )
//
// MSVC: [[TYPE_OF_FOUR]] = distinct !DICompositeType
// MSVC-SAME: tag: DW_TAG_class_type
// MSVC-SAME: name: "<lambda_0>"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,9 +51,9 @@ void test() {
// CHECK-SAME: name: "<lambda_2_1>",
c.lambda_params();

// CHECK: !DISubprogram(name: "operator()", scope: ![[LAMBDA1:[0-9]+]],
// CHECK: ![[LAMBDA1]] = !DICompositeType(tag: DW_TAG_class_type,
// CHECK: ![[LAMBDA1:[0-9]+]] = !DICompositeType(tag: DW_TAG_class_type,
// CHECK-SAME: name: "<lambda_1>",
// CHECK-SAME: flags: DIFlagFwdDecl
// CHECK: !DISubprogram(name: "operator()", scope: ![[LAMBDA1]],
c.lambda2();
}
Loading
Loading