[codeview] Make function names more consistent with MSVC
Names in function id records don't include nested name specifiers or
template arguments, but names in the symbol stream include both.
For the symbol stream, instead of having Clang put the fully qualified
name in the subprogram display name, recreate it from the subprogram
scope chain. For the type stream, take the unqualified name and chop of
any template arguments.
This makes it so that CodeView DI metadata is more similar to DWARF DI
metadata.
llvm-svn: 273009
diff --git a/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp b/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp
index 5ba7682..47adfc7 100644
--- a/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp
+++ b/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp
@@ -135,7 +135,9 @@
return I->second;
TypeIndex ParentScope = TypeIndex(0);
- StringRef DisplayName = SP->getDisplayName();
+ // The display name includes function template arguments. Drop them to match
+ // MSVC.
+ StringRef DisplayName = SP->getDisplayName().split('<').first;
FuncIdRecord FuncId(ParentScope, getTypeIndex(SP->getType()), DisplayName);
TypeIndex TI = TypeTable.writeFuncId(FuncId);
@@ -453,6 +455,31 @@
emitCodeViewMagicVersion();
}
+static const DISubprogram *getQualifiedNameComponents(
+ const DIScope *Scope, SmallVectorImpl<StringRef> &QualifiedNameComponents) {
+ const DISubprogram *ClosestSubprogram = nullptr;
+ while (Scope != nullptr) {
+ if (ClosestSubprogram == nullptr)
+ ClosestSubprogram = dyn_cast<DISubprogram>(Scope);
+ StringRef ScopeName = Scope->getName();
+ if (!ScopeName.empty())
+ QualifiedNameComponents.push_back(ScopeName);
+ Scope = Scope->getScope().resolve();
+ }
+ return ClosestSubprogram;
+}
+
+static std::string getQualifiedName(ArrayRef<StringRef> QualifiedNameComponents,
+ StringRef TypeName) {
+ std::string FullyQualifiedName;
+ for (StringRef QualifiedNameComponent : reverse(QualifiedNameComponents)) {
+ FullyQualifiedName.append(QualifiedNameComponent);
+ FullyQualifiedName.append("::");
+ }
+ FullyQualifiedName.append(TypeName);
+ return FullyQualifiedName;
+}
+
void CodeViewDebug::emitDebugInfoForFunction(const Function *GV,
FunctionInfo &FI) {
// For each function there is a separate subsection
@@ -463,11 +490,18 @@
// Switch to the to a comdat section, if appropriate.
switchToDebugSectionForSymbol(Fn);
- StringRef FuncName;
+ std::string FuncName;
auto *SP = GV->getSubprogram();
setCurrentSubprogram(SP);
- if (SP != nullptr)
- FuncName = SP->getDisplayName();
+
+ // If we have a display name, build the fully qualified name by walking the
+ // chain of scopes.
+ if (SP != nullptr && !SP->getDisplayName().empty()) {
+ SmallVector<StringRef, 5> QualifiedNameComponents;
+ getQualifiedNameComponents(SP->getScope().resolve(),
+ QualifiedNameComponents);
+ FuncName = getQualifiedName(QualifiedNameComponents, SP->getDisplayName());
+ }
// If our DISubprogram name is empty, use the mangled name.
if (FuncName.empty())
@@ -769,31 +803,6 @@
}
}
-static const DISubprogram *getQualifiedNameComponents(
- const DIScope *Scope, SmallVectorImpl<StringRef> &QualifiedNameComponents) {
- const DISubprogram *ClosestSubprogram = nullptr;
- while (Scope != nullptr) {
- if (ClosestSubprogram == nullptr)
- ClosestSubprogram = dyn_cast<DISubprogram>(Scope);
- StringRef ScopeName = Scope->getName();
- if (!ScopeName.empty())
- QualifiedNameComponents.push_back(ScopeName);
- Scope = Scope->getScope().resolve();
- }
- return ClosestSubprogram;
-}
-
-static std::string getQualifiedName(ArrayRef<StringRef> QualifiedNameComponents,
- StringRef TypeName) {
- std::string FullyQualifiedName;
- for (StringRef QualifiedNameComponent : reverse(QualifiedNameComponents)) {
- FullyQualifiedName.append(QualifiedNameComponent);
- FullyQualifiedName.append("::");
- }
- FullyQualifiedName.append(TypeName);
- return FullyQualifiedName;
-}
-
TypeIndex CodeViewDebug::lowerTypeAlias(const DIDerivedType *Ty) {
DITypeRef UnderlyingTypeRef = Ty->getBaseType();
TypeIndex UnderlyingTypeIndex = getTypeIndex(UnderlyingTypeRef);