r332975 - [CodeView] Enable debugging of captured variables within C++ lambdas
Brock Wyma via cfe-commits
cfe-commits at lists.llvm.org
Tue May 22 05:41:19 PDT 2018
Author: bwyma
Date: Tue May 22 05:41:19 2018
New Revision: 332975
URL: http://llvm.org/viewvc/llvm-project?rev=332975&view=rev
Log:
[CodeView] Enable debugging of captured variables within C++ lambdas
This change will help Visual Studio resolve forward references to C++ lambda
routines used by captured variables.
Differential Revision: https://reviews.llvm.org/D45438
Added:
cfe/trunk/test/CodeGen/debug-info-codeview-unnamed.c
cfe/trunk/test/CodeGenCXX/debug-info-codeview-unnamed.cpp
Modified:
cfe/trunk/lib/CodeGen/CGDebugInfo.cpp
Modified: cfe/trunk/lib/CodeGen/CGDebugInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGDebugInfo.cpp?rev=332975&r1=332974&r2=332975&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGDebugInfo.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGDebugInfo.cpp Tue May 22 05:41:19 2018
@@ -801,22 +801,46 @@ static bool hasCXXMangling(const TagDecl
}
}
-/// In C++ mode, types have linkage, so we can rely on the ODR and
-/// on their mangled names, if they're external.
-static SmallString<256> getUniqueTagTypeName(const TagType *Ty,
- CodeGenModule &CGM,
- llvm::DICompileUnit *TheCU) {
- SmallString<256> FullName;
+// Determines if the tag declaration will require a type identifier.
+static bool needsTypeIdentifier(const TagDecl *TD,
+ CodeGenModule& CGM,
+ llvm::DICompileUnit *TheCU) {
+ // We only add a type identifier for types with C++ name mangling.
+ if (!hasCXXMangling(TD, TheCU))
+ return false;
+
+ // CodeView types with C++ mangling need a type identifier.
+ if (CGM.getCodeGenOpts().EmitCodeView)
+ return true;
+
+ // Externally visible types with C++ mangling need a type identifier.
+ if (TD->isExternallyVisible())
+ return true;
+
+ return false;
+}
+
+// When emitting CodeView debug information we need to produce a type
+// identifier for all types which have a C++ mangling. Until a GUID is added
+// to the identifier (not currently implemented) the result will not be unique
+// across compilation units.
+// When emitting DWARF debug information, we need to produce a type identifier
+// for all externally visible types with C++ name mangling. This identifier
+// should be unique across ODR-compliant compilation units.
+static SmallString<256> getTypeIdentifier(const TagType *Ty,
+ CodeGenModule &CGM,
+ llvm::DICompileUnit *TheCU) {
+ SmallString<256> Identifier;
const TagDecl *TD = Ty->getDecl();
- if (!hasCXXMangling(TD, TheCU) || !TD->isExternallyVisible())
- return FullName;
+ if (!needsTypeIdentifier(TD, CGM, TheCU))
+ return Identifier;
// TODO: This is using the RTTI name. Is there a better way to get
// a unique string for a type?
- llvm::raw_svector_ostream Out(FullName);
+ llvm::raw_svector_ostream Out(Identifier);
CGM.getCXXABI().getMangleContext().mangleCXXRTTIName(QualType(Ty, 0), Out);
- return FullName;
+ return Identifier;
}
/// \return the appropriate DWARF tag for a composite type.
@@ -849,10 +873,10 @@ CGDebugInfo::getOrCreateRecordFwdDecl(co
uint32_t Align = 0;
// Create the type.
- SmallString<256> FullName = getUniqueTagTypeName(Ty, CGM, TheCU);
+ SmallString<256> Identifier = getTypeIdentifier(Ty, CGM, TheCU);
llvm::DICompositeType *RetTy = DBuilder.createReplaceableCompositeType(
getTagForRecord(RD), RDName, Ctx, DefUnit, Line, 0, Size, Align,
- llvm::DINode::FlagFwdDecl, FullName);
+ llvm::DINode::FlagFwdDecl, Identifier);
if (CGM.getCodeGenOpts().DebugFwdTemplateParams)
if (auto *TSpecial = dyn_cast<ClassTemplateSpecializationDecl>(RD))
DBuilder.replaceArrays(RetTy, llvm::DINodeArray(),
@@ -2477,7 +2501,7 @@ llvm::DIType *CGDebugInfo::CreateEnumTyp
Align = getDeclAlignIfRequired(ED, CGM.getContext());
}
- SmallString<256> FullName = getUniqueTagTypeName(Ty, CGM, TheCU);
+ SmallString<256> Identifier = getTypeIdentifier(Ty, CGM, TheCU);
bool isImportedFromModule =
DebugTypeExtRefs && ED->isFromASTFile() && ED->getDefinition();
@@ -2500,7 +2524,7 @@ llvm::DIType *CGDebugInfo::CreateEnumTyp
StringRef EDName = ED->getName();
llvm::DIType *RetTy = DBuilder.createReplaceableCompositeType(
llvm::dwarf::DW_TAG_enumeration_type, EDName, EDContext, DefUnit, Line,
- 0, Size, Align, llvm::DINode::FlagFwdDecl, FullName);
+ 0, Size, Align, llvm::DINode::FlagFwdDecl, Identifier);
ReplaceMap.emplace_back(
std::piecewise_construct, std::make_tuple(Ty),
@@ -2520,7 +2544,7 @@ llvm::DIType *CGDebugInfo::CreateTypeDef
Align = getDeclAlignIfRequired(ED, CGM.getContext());
}
- SmallString<256> FullName = getUniqueTagTypeName(Ty, CGM, TheCU);
+ SmallString<256> Identifier = getTypeIdentifier(Ty, CGM, TheCU);
// Create elements for each enumerator.
SmallVector<llvm::Metadata *, 16> Enumerators;
@@ -2542,7 +2566,7 @@ llvm::DIType *CGDebugInfo::CreateTypeDef
llvm::DIType *ClassTy = getOrCreateType(ED->getIntegerType(), DefUnit);
return DBuilder.createEnumerationType(EnumContext, ED->getName(), DefUnit,
Line, Size, Align, EltArray, ClassTy,
- FullName, ED->isFixed());
+ Identifier, ED->isFixed());
}
llvm::DIMacro *CGDebugInfo::CreateMacro(llvm::DIMacroFile *Parent,
@@ -2843,7 +2867,7 @@ llvm::DICompositeType *CGDebugInfo::Crea
uint64_t Size = CGM.getContext().getTypeSize(Ty);
auto Align = getDeclAlignIfRequired(D, CGM.getContext());
- SmallString<256> FullName = getUniqueTagTypeName(Ty, CGM, TheCU);
+ SmallString<256> Identifier = getTypeIdentifier(Ty, CGM, TheCU);
// Explicitly record the calling convention for C++ records.
auto Flags = llvm::DINode::FlagZero;
@@ -2856,7 +2880,7 @@ llvm::DICompositeType *CGDebugInfo::Crea
llvm::DICompositeType *RealDecl = DBuilder.createReplaceableCompositeType(
getTagForRecord(RD), RDName, RDContext, DefUnit, Line, 0, Size, Align,
- Flags, FullName);
+ Flags, Identifier);
// Elements of composite types usually have back to the type, creating
// uniquing cycles. Distinct nodes are more efficient.
@@ -2870,7 +2894,7 @@ llvm::DICompositeType *CGDebugInfo::Crea
// so they don't tend to be involved in uniquing cycles and there is some
// chance of merging them when linking together two modules. Only make
// them distinct if they are ODR-uniqued.
- if (FullName.empty())
+ if (Identifier.empty())
break;
LLVM_FALLTHROUGH;
Added: cfe/trunk/test/CodeGen/debug-info-codeview-unnamed.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/debug-info-codeview-unnamed.c?rev=332975&view=auto
==============================================================================
--- cfe/trunk/test/CodeGen/debug-info-codeview-unnamed.c (added)
+++ cfe/trunk/test/CodeGen/debug-info-codeview-unnamed.c Tue May 22 05:41:19 2018
@@ -0,0 +1,30 @@
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -debug-info-kind=limited -S -emit-llvm -o - %s | FileCheck --check-prefix LINUX %s
+// RUN: %clang_cc1 -triple x86_64-windows-msvc -debug-info-kind=limited -gcodeview -S -emit-llvm -o - %s | FileCheck --check-prefix MSVC %s
+
+int main(int argc, char* argv[], char* arge[]) {
+
+ // In both DWARF and CodeView, an unnamed C structure type will generate a
+ // DICompositeType without a name or identifier attribute;
+ //
+ 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-SAME: tag: DW_TAG_structure_type
+ // LINUX-NOT: name:
+ // LINUX-NOT: identifier:
+ // 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-NOT: name:
+ // MSVC-NOT: identifier:
+ // MSVC-SAME: )
+
+ return 0;
+}
Added: cfe/trunk/test/CodeGenCXX/debug-info-codeview-unnamed.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/debug-info-codeview-unnamed.cpp?rev=332975&view=auto
==============================================================================
--- cfe/trunk/test/CodeGenCXX/debug-info-codeview-unnamed.cpp (added)
+++ cfe/trunk/test/CodeGenCXX/debug-info-codeview-unnamed.cpp Tue May 22 05:41:19 2018
@@ -0,0 +1,108 @@
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -debug-info-kind=limited -S -emit-llvm -std=c++11 -o - %s | FileCheck --check-prefix LINUX %s
+// RUN: %clang_cc1 -triple x86_64-windows-msvc -debug-info-kind=limited -gcodeview -S -emit-llvm -std=c++11 -o - %s | FileCheck --check-prefix MSVC %s
+
+int main(int argc, char* argv[], char* arge[]) {
+ //
+ // 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: )
+ //
+ // 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.
+ //
+ struct { int bar; } two = { 42 };
+ 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: )
+ //
+ // 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: )
+ //
+ // 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
+ // of the LF_CLASS to its definition.
+ //
+ 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: )
+ //
+ // 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-NOT: name:
+ // MSVC-SAME: identifier: ".?AV<lambda_0>@?0??main@@9@"
+ // MSVC-SAME: )
+
+ return 0;
+}
More information about the cfe-commits
mailing list