diff options
author | Brock Wyma <brock.wyma@intel.com> | 2018-05-22 12:41:19 +0000 |
---|---|---|
committer | Brock Wyma <brock.wyma@intel.com> | 2018-05-22 12:41:19 +0000 |
commit | 8557ec5d642a86bc7d0fa3d95f5f6023a7b7cb26 (patch) | |
tree | 9faadd3f29ed7f6427e643ff94f2d4d272e4be98 /clang/lib/CodeGen/CGDebugInfo.cpp | |
parent | 067ec70d4fcbfc6bbb437110d94bf7e301717cd8 (diff) | |
download | bcm5719-llvm-8557ec5d642a86bc7d0fa3d95f5f6023a7b7cb26.tar.gz bcm5719-llvm-8557ec5d642a86bc7d0fa3d95f5f6023a7b7cb26.zip |
[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
llvm-svn: 332975
Diffstat (limited to 'clang/lib/CodeGen/CGDebugInfo.cpp')
-rw-r--r-- | clang/lib/CodeGen/CGDebugInfo.cpp | 62 |
1 files changed, 43 insertions, 19 deletions
diff --git a/clang/lib/CodeGen/CGDebugInfo.cpp b/clang/lib/CodeGen/CGDebugInfo.cpp index 55f96618ea4..9e99a646b0b 100644 --- a/clang/lib/CodeGen/CGDebugInfo.cpp +++ b/clang/lib/CodeGen/CGDebugInfo.cpp @@ -801,22 +801,46 @@ static bool hasCXXMangling(const TagDecl *TD, llvm::DICompileUnit *TheCU) { } } -/// 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(const RecordType *Ty, 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::CreateEnumType(const EnumType *Ty) { 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::CreateEnumType(const EnumType *Ty) { 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::CreateTypeDefinition(const EnumType *Ty) { 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::CreateTypeDefinition(const EnumType *Ty) { 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::CreateLimitedType(const RecordType *Ty) { 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::CreateLimitedType(const RecordType *Ty) { 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::CreateLimitedType(const RecordType *Ty) { // 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; |