aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp
diff options
context:
space:
mode:
authorAmy Huang <akhuang@google.com>2020-10-27 11:35:57 -0700
committerAmy Huang <akhuang@google.com>2020-10-28 16:35:59 -0700
commit7669f3c0f69db78cdd3deef066abc99f60fc580d (patch)
tree7b40ca4ffae302cff9524c78b24e7d0c8bda7338 /llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp
parentde518673436ecea229076827ee1f3131482d8f41 (diff)
downloadllvm-7669f3c0f69db78cdd3deef066abc99f60fc580d.zip
llvm-7669f3c0f69db78cdd3deef066abc99f60fc580d.tar.gz
llvm-7669f3c0f69db78cdd3deef066abc99f60fc580d.tar.bz2
Recommit "[CodeView] Emit static data members as S_CONSTANTs."
We used to only emit static const data members in CodeView as S_CONSTANTS when they were used; this patch makes it so they are always emitted. This changes CodeViewDebug.cpp to find the static const members from the class debug info instead of creating DIGlobalVariables in the IR whenever a static const data member is used. Bug: https://bugs.llvm.org/show_bug.cgi?id=47580 Differential Revision: https://reviews.llvm.org/D89072 This reverts commit 504615353f31136dd6bf7a971b6c236fd70582be.
Diffstat (limited to 'llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp')
-rw-r--r--llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp72
1 files changed, 68 insertions, 4 deletions
diff --git a/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp b/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp
index 98fccf0..125fea7 100644
--- a/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp
+++ b/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp
@@ -588,13 +588,18 @@ void CodeViewDebug::endModule() {
if (!P.first->isDeclarationForLinker())
emitDebugInfoForFunction(P.first, *P.second);
- // Emit global variable debug information.
- setCurrentSubprogram(nullptr);
- emitDebugInfoForGlobals();
+ // Get types used by globals without emitting anything.
+ // This is meant to collect all static const data members so they can be
+ // emitted as globals.
+ collectDebugInfoForGlobals();
// Emit retained types.
emitDebugInfoForRetainedTypes();
+ // Emit global variable debug information.
+ setCurrentSubprogram(nullptr);
+ emitDebugInfoForGlobals();
+
// Switch back to the generic .debug$S section after potentially processing
// comdat symbol sections.
switchToDebugSectionForSymbol(nullptr);
@@ -2143,6 +2148,12 @@ void CodeViewDebug::collectMemberInfo(ClassInfo &Info,
const DIDerivedType *DDTy) {
if (!DDTy->getName().empty()) {
Info.Members.push_back({DDTy, 0});
+
+ // Collect static const data members.
+ if ((DDTy->getFlags() & DINode::FlagStaticMember) ==
+ DINode::FlagStaticMember)
+ StaticConstMembers.push_back(DDTy);
+
return;
}
@@ -3045,15 +3056,32 @@ void CodeViewDebug::collectGlobalVariableInfo() {
}
}
+void CodeViewDebug::collectDebugInfoForGlobals() {
+ for (const CVGlobalVariable &CVGV : GlobalVariables) {
+ const DIGlobalVariable *DIGV = CVGV.DIGV;
+ const DIScope *Scope = DIGV->getScope();
+ getCompleteTypeIndex(DIGV->getType());
+ getFullyQualifiedName(Scope, DIGV->getName());
+ }
+
+ for (const CVGlobalVariable &CVGV : ComdatVariables) {
+ const DIGlobalVariable *DIGV = CVGV.DIGV;
+ const DIScope *Scope = DIGV->getScope();
+ getCompleteTypeIndex(DIGV->getType());
+ getFullyQualifiedName(Scope, DIGV->getName());
+ }
+}
+
void CodeViewDebug::emitDebugInfoForGlobals() {
// First, emit all globals that are not in a comdat in a single symbol
// substream. MSVC doesn't like it if the substream is empty, so only open
// it if we have at least one global to emit.
switchToDebugSectionForSymbol(nullptr);
- if (!GlobalVariables.empty()) {
+ if (!GlobalVariables.empty() || !StaticConstMembers.empty()) {
OS.AddComment("Symbol subsection for globals");
MCSymbol *EndLabel = beginCVSubsection(DebugSubsectionKind::Symbols);
emitGlobalVariableList(GlobalVariables);
+ emitStaticConstMemberList();
endCVSubsection(EndLabel);
}
@@ -3092,6 +3120,42 @@ void CodeViewDebug::emitGlobalVariableList(ArrayRef<CVGlobalVariable> Globals) {
}
}
+void CodeViewDebug::emitStaticConstMemberList() {
+ for (const DIDerivedType *DTy : StaticConstMembers) {
+ const DIScope *Scope = DTy->getScope();
+
+ APSInt Value;
+ if (const ConstantInt *CI =
+ dyn_cast_or_null<ConstantInt>(DTy->getConstant()))
+ Value = APSInt(CI->getValue(),
+ DebugHandlerBase::isUnsignedDIType(DTy->getBaseType()));
+ else if (const ConstantFP *CFP =
+ dyn_cast_or_null<ConstantFP>(DTy->getConstant()))
+ Value = APSInt(CFP->getValueAPF().bitcastToAPInt(), true);
+ else
+ continue;
+
+ std::string QualifiedName = getFullyQualifiedName(Scope, DTy->getName());
+
+ MCSymbol *SConstantEnd = beginSymbolRecord(SymbolKind::S_CONSTANT);
+ OS.AddComment("Type");
+ OS.emitInt32(getTypeIndex(DTy->getBaseType()).getIndex());
+ OS.AddComment("Value");
+
+ // Encoded integers shouldn't need more than 10 bytes.
+ uint8_t Data[10];
+ BinaryStreamWriter Writer(Data, llvm::support::endianness::little);
+ CodeViewRecordIO IO(Writer);
+ cantFail(IO.mapEncodedInteger(Value));
+ StringRef SRef((char *)Data, Writer.getOffset());
+ OS.emitBinaryData(SRef);
+
+ OS.AddComment("Name");
+ emitNullTerminatedSymbolName(OS, QualifiedName);
+ endSymbolRecord(SConstantEnd);
+ }
+}
+
void CodeViewDebug::emitDebugInfoForGlobal(const CVGlobalVariable &CVGV) {
const DIGlobalVariable *DIGV = CVGV.DIGV;