34 #include "llvm/Config/llvm-config.h"
84 : OS(&OS), TypeTable(TypeTable) {}
86 void emitBytes(
StringRef Data)
override { OS->emitBytes(Data); }
89 OS->emitIntValueInHex(
Value, Size);
92 void emitBinaryData(
StringRef Data)
override { OS->emitBinaryData(Data); }
94 void AddComment(
const Twine &
T)
override { OS->AddComment(
T); }
96 void AddRawComment(
const Twine &
T)
override { OS->emitRawComment(
T); }
98 bool isVerboseAsm()
override {
return OS->isVerboseAsm(); }
106 TypeName = std::string(TypeTable.getTypeName(TI));
121 case Triple::ArchType::x86_64:
123 case Triple::ArchType::thumb:
127 case Triple::ArchType::aarch64:
138 std::string &Filepath = FileToFilepathMap[File];
139 if (!Filepath.empty())
142 StringRef Dir = File->getDirectory(), Filename = File->getFilename();
146 if (Dir.
startswith(
"/") || Filename.startswith(
"/")) {
149 Filepath = std::string(Dir);
150 if (Dir.
back() !=
'/')
152 Filepath += Filename;
160 if (Filename.find(
':') == 1)
161 Filepath = std::string(Filename);
163 Filepath = (Dir +
"\\" + Filename).str();
168 std::replace(Filepath.begin(), Filepath.end(),
'/',
'\\');
172 while ((Cursor = Filepath.find(
"\\.\\", Cursor)) != std::string::npos)
173 Filepath.erase(Cursor, 2);
178 while ((Cursor = Filepath.find(
"\\..\\", Cursor)) != std::string::npos) {
183 size_t PrevSlash = Filepath.rfind(
'\\', Cursor - 1);
184 if (PrevSlash == std::string::npos)
188 Filepath.erase(PrevSlash, Cursor + 3 - PrevSlash);
195 while ((Cursor = Filepath.find(
"\\\\", Cursor)) != std::string::npos)
196 Filepath.erase(Cursor, 1);
201 unsigned CodeViewDebug::maybeRecordFile(
const DIFile *
F) {
203 unsigned NextId = FileIdMap.
size() + 1;
204 auto Insertion = FileIdMap.
insert(std::make_pair(FullPath, NextId));
205 if (Insertion.second) {
209 if (
F->getChecksum()) {
210 std::string Checksum = fromHex(
F->getChecksum()->Value);
212 memcpy(CKMem, Checksum.data(), Checksum.size());
214 reinterpret_cast<const uint8_t *
>(CKMem), Checksum.size());
215 switch (
F->getChecksum()->Kind) {
217 CSKind = FileChecksumKind::MD5;
220 CSKind = FileChecksumKind::SHA1;
223 CSKind = FileChecksumKind::SHA256;
228 static_cast<unsigned>(CSKind));
232 return Insertion.first->second;
236 CodeViewDebug::getInlineSite(
const DILocation *InlinedAt,
238 auto SiteInsertion = CurFn->InlineSites.insert({InlinedAt,
InlineSite()});
239 InlineSite *Site = &SiteInsertion.first->second;
240 if (SiteInsertion.second) {
241 unsigned ParentFuncId = CurFn->FuncId;
242 if (
const DILocation *OuterIA = InlinedAt->getInlinedAt())
244 getInlineSite(OuterIA, InlinedAt->getScope()->getSubprogram())
247 Site->SiteFuncId = NextFuncId++;
249 Site->SiteFuncId, ParentFuncId, maybeRecordFile(InlinedAt->getFile()),
250 InlinedAt->getLine(), InlinedAt->getColumn(),
SMLoc());
252 InlinedSubprograms.insert(Inlinee);
253 getFuncIdForSubprogram(Inlinee);
260 if (!ScopeName.
empty())
263 switch (
Scope->getTag()) {
264 case dwarf::DW_TAG_enumeration_type:
265 case dwarf::DW_TAG_class_type:
266 case dwarf::DW_TAG_structure_type:
267 case dwarf::DW_TAG_union_type:
268 return "<unnamed-tag>";
269 case dwarf::DW_TAG_namespace:
270 return "`anonymous namespace'";
276 const DISubprogram *CodeViewDebug::collectParentScopeNames(
279 while (
Scope !=
nullptr) {
280 if (ClosestSubprogram ==
nullptr)
281 ClosestSubprogram = dyn_cast<DISubprogram>(
Scope);
286 if (
const auto *Ty = dyn_cast<DICompositeType>(
Scope))
287 DeferredCompleteTypes.push_back(Ty);
290 if (!ScopeName.
empty())
291 QualifiedNameComponents.push_back(ScopeName);
294 return ClosestSubprogram;
299 std::string FullyQualifiedName;
302 FullyQualifiedName.append(std::string(QualifiedNameComponent));
303 FullyQualifiedName.append(
"::");
305 FullyQualifiedName.append(std::string(
TypeName));
306 return FullyQualifiedName;
314 if (
CVD.TypeEmissionLevel == 1)
315 CVD.emitDeferredCompleteTypes();
316 --
CVD.TypeEmissionLevel;
321 std::string CodeViewDebug::getFullyQualifiedName(
const DIScope *
Scope,
328 collectParentScopeNames(
Scope, QualifiedNameComponents);
332 std::string CodeViewDebug::getFullyQualifiedName(
const DIScope *Ty) {
351 assert(!isa<DIType>(
Scope) &&
"shouldn't make a namespace scope for a type");
354 auto I = TypeIndices.find({
Scope,
nullptr});
355 if (
I != TypeIndices.end())
359 std::string ScopeName = getFullyQualifiedName(
Scope);
362 return recordTypeIndexForDINode(
Scope, TI);
368 if (
Name.empty() ||
Name.back() !=
'>')
371 int OpenBrackets = 0;
372 for (
int i =
Name.size() - 1;
i >= 0; --
i) {
375 else if (
Name[
i] ==
'<') {
377 if (OpenBrackets == 0)
378 return Name.substr(0,
i);
388 auto I = TypeIndices.find({SP,
nullptr});
389 if (
I != TypeIndices.end())
399 if (
const auto *Class = dyn_cast_or_null<DICompositeType>(
Scope)) {
403 TypeIndex ClassType = getTypeIndex(Class);
414 return recordTypeIndexForDINode(SP, TI);
418 return ((DCTy->
getFlags() & DINode::FlagNonTrivial) == DINode::FlagNonTrivial);
426 const DIType *ReturnTy =
nullptr;
428 if (TypeArray.size())
429 ReturnTy = TypeArray[0];
434 if (
auto *ReturnDCTy = dyn_cast_or_null<DICompositeType>(ReturnTy))
436 FO |= FunctionOptions::CxxReturnUdt;
439 if (ClassTy &&
isNonTrivial(ClassTy) && SPName == ClassTy->getName()) {
440 FO |= FunctionOptions::Constructor;
452 if (SP->getDeclaration())
453 SP = SP->getDeclaration();
454 assert(!SP->getDeclaration() &&
"should use declaration as key");
458 auto I = TypeIndices.find({SP,
Class});
459 if (
I != TypeIndices.end())
465 TypeLoweringScope
S(*
this);
466 const bool IsStaticMethod = (SP->getFlags() & DINode::FlagStaticMember) != 0;
470 SP->getType(), Class, SP->getThisAdjustment(), IsStaticMethod, FO);
471 return recordTypeIndexForDINode(SP, TI, Class);
477 auto InsertResult = TypeIndices.insert({{Node, ClassTy}, TI});
479 assert(InsertResult.second &&
"DINode was already assigned a type index");
483 unsigned CodeViewDebug::getPointerSizeInBytes() {
487 void CodeViewDebug::recordLocalVariable(LocalVariable &&Var,
492 InlineSite &Site = getInlineSite(InlinedAt, Inlinee);
493 Site.InlinedLocals.emplace_back(Var);
496 ScopeVariables[
LS].emplace_back(Var);
506 void CodeViewDebug::maybeRecordLocation(
const DebugLoc &
DL,
518 if (LI.getStartLine() !=
DL.getLine() || LI.isAlwaysStepInto() ||
519 LI.isNeverStepInto())
523 if (CI.getStartColumn() !=
DL.getCol())
526 if (!CurFn->HaveLineInfo)
527 CurFn->HaveLineInfo =
true;
530 FileId = CurFn->LastFileId;
532 FileId = CurFn->LastFileId = maybeRecordFile(
DL->getFile());
535 unsigned FuncId = CurFn->FuncId;
542 getInlineSite(SiteLoc, Loc->getScope()->getSubprogram()).SiteFuncId;
545 bool FirstLoc =
true;
546 while ((SiteLoc = Loc->getInlinedAt())) {
548 getInlineSite(SiteLoc, Loc->getScope()->getSubprogram());
562 void CodeViewDebug::emitCodeViewMagicVersion() {
570 case dwarf::DW_LANG_C:
571 case dwarf::DW_LANG_C89:
572 case dwarf::DW_LANG_C99:
573 case dwarf::DW_LANG_C11:
574 case dwarf::DW_LANG_ObjC:
576 case dwarf::DW_LANG_C_plus_plus:
577 case dwarf::DW_LANG_C_plus_plus_03:
578 case dwarf::DW_LANG_C_plus_plus_11:
579 case dwarf::DW_LANG_C_plus_plus_14:
581 case dwarf::DW_LANG_Fortran77:
582 case dwarf::DW_LANG_Fortran90:
583 case dwarf::DW_LANG_Fortran95:
584 case dwarf::DW_LANG_Fortran03:
585 case dwarf::DW_LANG_Fortran08:
587 case dwarf::DW_LANG_Pascal83:
589 case dwarf::DW_LANG_Cobol74:
590 case dwarf::DW_LANG_Cobol85:
592 case dwarf::DW_LANG_Java:
594 case dwarf::DW_LANG_D:
596 case dwarf::DW_LANG_Swift:
598 case dwarf::DW_LANG_Rust:
620 const MDNode *Node = *
M->debug_compile_units_begin();
621 const auto *
CU = cast<DICompileUnit>(Node);
625 collectGlobalVariableInfo();
629 mdconst::extract_or_null<ConstantInt>(
M->getModuleFlag(
"CodeViewGHash"));
630 EmitDebugGlobalHashes = GH && !GH->
isZero();
644 switchToDebugSectionForSymbol(
nullptr);
646 MCSymbol *CompilerInfo = beginCVSubsection(DebugSubsectionKind::Symbols);
648 emitCompilerInformation();
649 endCVSubsection(CompilerInfo);
651 emitInlineeLinesSubsection();
654 for (
auto &
P : FnDebugInfo)
655 if (!
P.first->isDeclarationForLinker())
656 emitDebugInfoForFunction(
P.first, *
P.second);
661 collectDebugInfoForGlobals();
664 emitDebugInfoForRetainedTypes();
667 setCurrentSubprogram(
nullptr);
668 emitDebugInfoForGlobals();
672 switchToDebugSectionForSymbol(
nullptr);
675 if (!GlobalUDTs.empty()) {
676 MCSymbol *SymbolsEnd = beginCVSubsection(DebugSubsectionKind::Symbols);
677 emitDebugInfoForUDTs(GlobalUDTs);
678 endCVSubsection(SymbolsEnd);
682 OS.
AddComment(
"File index to string table offset subsection");
696 emitTypeInformation();
698 if (EmitDebugGlobalHashes)
699 emitTypeGlobalHashes();
706 unsigned MaxFixedRecordLength = 0xF00) {
713 NullTerminatedString.push_back(
'\0');
717 void CodeViewDebug::emitTypeInformation() {
718 if (TypeTable.
empty())
723 emitCodeViewMagicVersion();
729 CVMCAdapter CVMCOS(OS, Table);
745 B = Table.getNext(*
B);
749 void CodeViewDebug::emitTypeGlobalHashes() {
750 if (TypeTable.
empty())
765 TypeIndex TI(TypeIndex::FirstNonSimpleIndex);
766 for (
const auto &GHR : TypeTable.
hashes()) {
776 assert(GHR.Hash.size() == 8);
777 StringRef S(
reinterpret_cast<const char *
>(GHR.Hash.data()),
783 void CodeViewDebug::emitObjName() {
784 MCSymbol *CompilerEnd = beginSymbolRecord(SymbolKind::S_OBJNAME);
789 if (PathRef.empty() || PathRef ==
"-") {
803 endSymbolRecord(CompilerEnd);
817 for (
const char C :
Name) {
820 V.Part[
N] +=
C -
'0';
823 }
else if (
C ==
'.') {
833 void CodeViewDebug::emitCompilerInformation() {
834 MCSymbol *CompilerEnd = beginSymbolRecord(SymbolKind::S_COMPILE3);
838 Flags = CurrentSourceLanguage;
841 Flags |=
static_cast<uint32_t>(CompileSym3Flags::PGO);
846 Arch == ArchType::aarch64) {
847 Flags |=
static_cast<uint32_t>(CompileSym3Flags::HotPatch);
858 const auto *
CU = cast<DICompileUnit>(Node);
863 for (
int N : FrontVer.Part) {
870 int Major = 1000 * LLVM_VERSION_MAJOR +
871 10 * LLVM_VERSION_MINOR +
875 Version BackVer = {{ Major, 0, 0, 0 }};
877 for (
int N : BackVer.Part)
880 OS.
AddComment(
"Null-terminated compiler version string");
883 endSymbolRecord(CompilerEnd);
894 std::string FlatCmdLine;
896 bool PrintedOneArg =
false;
899 PrintedOneArg =
true;
901 for (
unsigned i = 0;
i <
Args.size();
i++) {
905 if (
Arg ==
"-main-file-name" ||
Arg ==
"-o") {
909 if (
Arg.startswith(
"-object-file-name") ||
Arg == MainFilename)
914 PrintedOneArg =
true;
920 void CodeViewDebug::emitBuildInfo() {
931 TypeIndex BuildInfoArgs[BuildInfoRecord::MaxArgs] = {};
934 const auto *
CU = cast<DICompileUnit>(Node);
935 const DIFile *MainSourceFile =
CU->getFile();
936 BuildInfoArgs[BuildInfoRecord::CurrentDirectory] =
938 BuildInfoArgs[BuildInfoRecord::SourceFile] =
941 BuildInfoArgs[BuildInfoRecord::TypeServerPDB] =
944 BuildInfoArgs[BuildInfoRecord::BuildTool] =
955 MCSymbol *BISubsecEnd = beginCVSubsection(DebugSubsectionKind::Symbols);
956 MCSymbol *BIEnd = beginSymbolRecord(SymbolKind::S_BUILDINFO);
959 endSymbolRecord(BIEnd);
960 endCVSubsection(BISubsecEnd);
963 void CodeViewDebug::emitInlineeLinesSubsection() {
964 if (InlinedSubprograms.empty())
968 MCSymbol *InlineEnd = beginCVSubsection(DebugSubsectionKind::InlineeLines);
975 OS.
emitInt32(
unsigned(InlineeLinesSignature::Normal));
978 assert(TypeIndices.count({SP, nullptr}));
979 TypeIndex InlineeIdx = TypeIndices[{SP,
nullptr}];
982 unsigned FileId = maybeRecordFile(SP->
getFile());
986 OS.
AddComment(
"Type index of inlined function");
988 OS.
AddComment(
"Offset into filechecksum table");
994 endCVSubsection(InlineEnd);
997 void CodeViewDebug::emitInlinedCallSite(
const FunctionInfo &FI,
1000 assert(TypeIndices.count({Site.Inlinee, nullptr}));
1001 TypeIndex InlineeIdx = TypeIndices[{Site.Inlinee,
nullptr}];
1004 MCSymbol *InlineEnd = beginSymbolRecord(SymbolKind::S_INLINESITE);
1013 unsigned FileId = maybeRecordFile(Site.Inlinee->getFile());
1014 unsigned StartLineNum = Site.Inlinee->getLine();
1019 endSymbolRecord(InlineEnd);
1021 emitLocalVariableList(FI, Site.InlinedLocals);
1024 for (
const DILocation *ChildSite : Site.ChildSites) {
1025 auto I = FI.InlineSites.find(ChildSite);
1026 assert(
I != FI.InlineSites.end() &&
1027 "child site not in function inline site map");
1028 emitInlinedCallSite(FI, ChildSite,
I->second);
1032 emitEndSymbolRecord(SymbolKind::S_INLINESITE_END);
1035 void CodeViewDebug::switchToDebugSectionForSymbol(
const MCSymbol *GVSym) {
1040 GVSym ? dyn_cast<MCSectionCOFF>(&GVSym->
getSection()) : nullptr;
1051 if (ComdatDebugSections.insert(DebugSec).second)
1052 emitCodeViewMagicVersion();
1057 void CodeViewDebug::emitDebugInfoForThunk(
const Function *GV,
1060 std::string FuncName =
1065 MCSymbol *SymbolsEnd = beginCVSubsection(DebugSubsectionKind::Symbols);
1068 MCSymbol *ThunkRecordEnd = beginSymbolRecord(SymbolKind::S_THUNK32);
1075 OS.
AddComment(
"Thunk section relative address");
1086 endSymbolRecord(ThunkRecordEnd);
1092 emitEndSymbolRecord(SymbolKind::S_PROC_ID_END);
1094 endCVSubsection(SymbolsEnd);
1097 void CodeViewDebug::emitDebugInfoForFunction(
const Function *GV,
1105 switchToDebugSectionForSymbol(Fn);
1107 std::string FuncName;
1110 setCurrentSubprogram(SP);
1112 if (SP->isThunk()) {
1113 emitDebugInfoForThunk(GV, FI, Fn);
1123 if (FuncName.empty())
1132 MCSymbol *SymbolsEnd = beginCVSubsection(DebugSubsectionKind::Symbols);
1135 : SymbolKind::S_GPROC32_ID;
1136 MCSymbol *ProcRecordEnd = beginSymbolRecord(ProcKind);
1155 OS.
AddComment(
"Function section relative address");
1165 endSymbolRecord(ProcRecordEnd);
1167 MCSymbol *FrameProcEnd = beginSymbolRecord(SymbolKind::S_FRAMEPROC);
1170 OS.
emitInt32(FI.FrameSize - FI.CSRSize);
1175 OS.
AddComment(
"Bytes of callee saved registers");
1181 OS.
AddComment(
"Flags (defines frame register)");
1183 endSymbolRecord(FrameProcEnd);
1185 emitLocalVariableList(FI, FI.Locals);
1186 emitGlobalVariableList(FI.Globals);
1187 emitLexicalBlockList(FI.ChildBlocks, FI);
1192 for (
const DILocation *InlinedAt : FI.ChildSites) {
1193 auto I = FI.InlineSites.find(InlinedAt);
1194 assert(
I != FI.InlineSites.end() &&
1195 "child site not in function inline site map");
1196 emitInlinedCallSite(FI, InlinedAt,
I->second);
1199 for (
auto Annot : FI.Annotations) {
1201 MDTuple *Strs = cast<MDTuple>(Annot.second);
1202 MCSymbol *AnnotEnd = beginSymbolRecord(SymbolKind::S_ANNOTATION);
1210 StringRef Str = cast<MDString>(MD)->getString();
1211 assert(Str.data()[Str.size()] ==
'\0' &&
"non-nullterminated MDString");
1214 endSymbolRecord(AnnotEnd);
1217 for (
auto HeapAllocSite : FI.HeapAllocSites) {
1218 const MCSymbol *BeginLabel = std::get<0>(HeapAllocSite);
1219 const MCSymbol *EndLabel = std::get<1>(HeapAllocSite);
1220 const DIType *DITy = std::get<2>(HeapAllocSite);
1221 MCSymbol *HeapAllocEnd = beginSymbolRecord(SymbolKind::S_HEAPALLOCSITE);
1229 OS.
emitInt32(getCompleteTypeIndex(DITy).getIndex());
1230 endSymbolRecord(HeapAllocEnd);
1234 emitDebugInfoForUDTs(LocalUDTs);
1237 emitEndSymbolRecord(SymbolKind::S_PROC_ID_END);
1239 endCVSubsection(SymbolsEnd);
1246 CodeViewDebug::createDefRangeMem(
uint16_t CVRegister,
int Offset) {
1250 assert(DR.DataOffset == Offset &&
"truncation");
1252 DR.StructOffset = 0;
1253 DR.CVRegister = CVRegister;
1257 void CodeViewDebug::collectVariableInfoFromMFTable(
1267 assert(
VI.Var->isValidLocationForIntrinsic(
VI.Loc) &&
1268 "Expected inlined-at fields to agree");
1270 Processed.
insert(InlinedEntity(
VI.Var,
VI.Loc->getInlinedAt()));
1279 int64_t ExprOffset = 0;
1283 if (
VI.Expr->getNumElements() == 1 &&
1284 VI.Expr->getElement(0) == llvm::dwarf::DW_OP_deref)
1286 else if (!
VI.Expr->extractIfOffset(ExprOffset))
1296 "Frame offsets with a scalable component are not supported");
1299 LocalVarDef DefRange =
1300 createDefRangeMem(CVReg, FrameOffset.
getFixed() + ExprOffset);
1309 Var.DefRanges[DefRange].emplace_back(Begin, End);
1313 Var.UseReferenceType =
true;
1327 void CodeViewDebug::calculateRanges(
1332 for (
auto I = Entries.begin(),
E = Entries.end();
I !=
E; ++
I) {
1333 const auto &Entry = *
I;
1334 if (!Entry.isDbgValue())
1352 if (Var.UseReferenceType) {
1361 Var.UseReferenceType =
true;
1362 Var.DefRanges.clear();
1363 calculateRanges(Var, Entries);
1373 DR.InMemory = !
Location->LoadChain.empty();
1377 DR.IsSubfield =
true;
1378 DR.StructOffset =
Location->FragmentInfo->OffsetInBits / 8;
1380 DR.IsSubfield =
false;
1381 DR.StructOffset = 0;
1388 auto &EndingEntry = Entries[Entry.getEndIndex()];
1389 End = EndingEntry.isDbgValue()
1399 if (!
R.empty() &&
R.back().second == Begin)
1400 R.back().second = End;
1402 R.emplace_back(Begin, End);
1408 void CodeViewDebug::collectVariableInfo(
const DISubprogram *SP) {
1411 collectVariableInfoFromMFTable(Processed);
1414 InlinedEntity
IV =
I.first;
1421 const auto &Entries =
I.second;
1435 calculateRanges(Var, Entries);
1445 auto Insertion = FnDebugInfo.insert({&GV, std::make_unique<FunctionInfo>()});
1446 assert(Insertion.second &&
"function already has info");
1447 CurFn = Insertion.first->second.get();
1448 CurFn->FuncId = NextFuncId++;
1463 if (CurFn->FrameSize > 0) {
1465 CurFn->EncodedLocalFramePtrReg = EncodedFramePtrReg::StackPtr;
1466 CurFn->EncodedParamFramePtrReg = EncodedFramePtrReg::StackPtr;
1470 if (CurFn->HasStackRealignment) {
1472 CurFn->EncodedLocalFramePtrReg = EncodedFramePtrReg::StackPtr;
1484 FPO |= FrameProcedureOptions::HasAlloca;
1486 FPO |= FrameProcedureOptions::HasSetJmp;
1489 FPO |= FrameProcedureOptions::HasInlineAssembly;
1493 FPO |= FrameProcedureOptions::HasStructuredExceptionHandling;
1495 FPO |= FrameProcedureOptions::HasExceptionHandling;
1498 FPO |= FrameProcedureOptions::MarkedInline;
1500 FPO |= FrameProcedureOptions::Naked;
1502 FPO |= FrameProcedureOptions::SecurityChecks;
1507 FPO |= FrameProcedureOptions::OptimizedForSpeed;
1509 FPO |= FrameProcedureOptions::ValidProfileCounts;
1510 FPO |= FrameProcedureOptions::ProfileGuidedOptimization;
1513 CurFn->FrameProcOpts = FPO;
1522 bool EmptyPrologue =
true;
1523 for (
const auto &
MBB : *MF) {
1524 for (
const auto &
MI :
MBB) {
1529 }
else if (!
MI.isMetaInstruction()) {
1530 EmptyPrologue =
false;
1538 maybeRecordLocation(FnStartDL, MF);
1542 for (
const auto &
MBB : *MF) {
1543 for (
const auto &
MI :
MBB) {
1544 if (
MI.getHeapAllocMarker()) {
1557 if (
T->getTag() == dwarf::DW_TAG_typedef) {
1559 switch (
Scope->getTag()) {
1560 case dwarf::DW_TAG_structure_type:
1561 case dwarf::DW_TAG_class_type:
1562 case dwarf::DW_TAG_union_type:
1572 if (!
T ||
T->isForwardDecl())
1578 T = DT->getBaseType();
1583 void CodeViewDebug::addToUDTs(
const DIType *Ty) {
1592 collectParentScopeNames(Ty->
getScope(), ParentScopeNames);
1594 std::string FullyQualifiedName =
1597 if (ClosestSubprogram ==
nullptr) {
1598 GlobalUDTs.emplace_back(
std::move(FullyQualifiedName), Ty);
1599 }
else if (ClosestSubprogram == CurrentSubprogram) {
1600 LocalUDTs.emplace_back(
std::move(FullyQualifiedName), Ty);
1614 case dwarf::DW_TAG_array_type:
1615 return lowerTypeArray(cast<DICompositeType>(Ty));
1616 case dwarf::DW_TAG_typedef:
1617 return lowerTypeAlias(cast<DIDerivedType>(Ty));
1618 case dwarf::DW_TAG_base_type:
1619 return lowerTypeBasic(cast<DIBasicType>(Ty));
1620 case dwarf::DW_TAG_pointer_type:
1621 if (cast<DIDerivedType>(Ty)->
getName() ==
"__vtbl_ptr_type")
1622 return lowerTypeVFTableShape(cast<DIDerivedType>(Ty));
1624 case dwarf::DW_TAG_reference_type:
1625 case dwarf::DW_TAG_rvalue_reference_type:
1626 return lowerTypePointer(cast<DIDerivedType>(Ty));
1627 case dwarf::DW_TAG_ptr_to_member_type:
1628 return lowerTypeMemberPointer(cast<DIDerivedType>(Ty));
1629 case dwarf::DW_TAG_restrict_type:
1630 case dwarf::DW_TAG_const_type:
1631 case dwarf::DW_TAG_volatile_type:
1633 return lowerTypeModifier(cast<DIDerivedType>(Ty));
1634 case dwarf::DW_TAG_subroutine_type:
1638 return lowerTypeMemberFunction(cast<DISubroutineType>(Ty), ClassTy,
1642 return lowerTypeFunction(cast<DISubroutineType>(Ty));
1643 case dwarf::DW_TAG_enumeration_type:
1644 return lowerTypeEnum(cast<DICompositeType>(Ty));
1645 case dwarf::DW_TAG_class_type:
1646 case dwarf::DW_TAG_structure_type:
1647 return lowerTypeClass(cast<DICompositeType>(Ty));
1648 case dwarf::DW_TAG_union_type:
1649 return lowerTypeUnion(cast<DICompositeType>(Ty));
1650 case dwarf::DW_TAG_string_type:
1651 return lowerTypeString(cast<DIStringType>(Ty));
1652 case dwarf::DW_TAG_unspecified_type:
1653 if (Ty->
getName() ==
"decltype(nullptr)")
1654 return TypeIndex::NullptrT();
1663 TypeIndex UnderlyingTypeIndex = getTypeIndex(Ty->getBaseType());
1668 if (UnderlyingTypeIndex ==
TypeIndex(SimpleTypeKind::Int32Long) &&
1670 return TypeIndex(SimpleTypeKind::HResult);
1671 if (UnderlyingTypeIndex ==
TypeIndex(SimpleTypeKind::UInt16Short) &&
1673 return TypeIndex(SimpleTypeKind::WideCharacter);
1675 return UnderlyingTypeIndex;
1680 TypeIndex ElementTypeIndex = getTypeIndex(ElementType);
1682 TypeIndex IndexType = getPointerSizeInBytes() == 8
1690 for (
int i = Elements.size() - 1;
i >= 0; --
i) {
1691 const DINode *Element = Elements[
i];
1692 assert(Element->
getTag() == dwarf::DW_TAG_subrange_type);
1694 const DISubrange *Subrange = cast<DISubrange>(Element);
1702 Count = CI->getSExtValue();
1719 ElementSize *= Count;
1724 (
i == 0 && ElementSize == 0) ? Ty->
getSizeInBits() / 8 : ElementSize;
1731 return ElementTypeIndex;
1744 TypeIndex IndexType = getPointerSizeInBytes() == 8
1764 case dwarf::DW_ATE_address:
1767 case dwarf::DW_ATE_boolean:
1769 case 1: STK = SimpleTypeKind::Boolean8;
break;
1770 case 2: STK = SimpleTypeKind::Boolean16;
break;
1771 case 4: STK = SimpleTypeKind::Boolean32;
break;
1772 case 8: STK = SimpleTypeKind::Boolean64;
break;
1773 case 16: STK = SimpleTypeKind::Boolean128;
break;
1776 case dwarf::DW_ATE_complex_float:
1778 case 2: STK = SimpleTypeKind::Complex16;
break;
1779 case 4: STK = SimpleTypeKind::Complex32;
break;
1780 case 8: STK = SimpleTypeKind::Complex64;
break;
1781 case 10: STK = SimpleTypeKind::Complex80;
break;
1782 case 16: STK = SimpleTypeKind::Complex128;
break;
1785 case dwarf::DW_ATE_float:
1787 case 2: STK = SimpleTypeKind::Float16;
break;
1788 case 4: STK = SimpleTypeKind::Float32;
break;
1789 case 6: STK = SimpleTypeKind::Float48;
break;
1790 case 8: STK = SimpleTypeKind::Float64;
break;
1791 case 10: STK = SimpleTypeKind::Float80;
break;
1792 case 16: STK = SimpleTypeKind::Float128;
break;
1795 case dwarf::DW_ATE_signed:
1797 case 1: STK = SimpleTypeKind::SignedCharacter;
break;
1798 case 2: STK = SimpleTypeKind::Int16Short;
break;
1800 case 8: STK = SimpleTypeKind::Int64Quad;
break;
1801 case 16: STK = SimpleTypeKind::Int128Oct;
break;
1804 case dwarf::DW_ATE_unsigned:
1806 case 1: STK = SimpleTypeKind::UnsignedCharacter;
break;
1807 case 2: STK = SimpleTypeKind::UInt16Short;
break;
1809 case 8: STK = SimpleTypeKind::UInt64Quad;
break;
1810 case 16: STK = SimpleTypeKind::UInt128Oct;
break;
1813 case dwarf::DW_ATE_UTF:
1815 case 1: STK = SimpleTypeKind::Character8;
break;
1816 case 2: STK = SimpleTypeKind::Character16;
break;
1817 case 4: STK = SimpleTypeKind::Character32;
break;
1820 case dwarf::DW_ATE_signed_char:
1822 STK = SimpleTypeKind::SignedCharacter;
1824 case dwarf::DW_ATE_unsigned_char:
1826 STK = SimpleTypeKind::UnsignedCharacter;
1838 STK = SimpleTypeKind::Int32Long;
1840 Ty->
getName() ==
"unsigned long"))
1841 STK = SimpleTypeKind::UInt32Long;
1842 if (STK == SimpleTypeKind::UInt16Short &&
1844 STK = SimpleTypeKind::WideCharacter;
1845 if ((STK == SimpleTypeKind::SignedCharacter ||
1846 STK == SimpleTypeKind::UnsignedCharacter) &&
1848 STK = SimpleTypeKind::NarrowCharacter;
1855 TypeIndex PointeeTI = getTypeIndex(Ty->getBaseType());
1861 Ty->
getTag() == dwarf::DW_TAG_pointer_type) {
1863 ? SimpleTypeMode::NearPointer64
1864 : SimpleTypeMode::NearPointer32;
1869 Ty->
getSizeInBits() == 64 ? PointerKind::Near64 : PointerKind::Near32;
1873 case dwarf::DW_TAG_pointer_type:
1874 PM = PointerMode::Pointer;
1876 case dwarf::DW_TAG_reference_type:
1877 PM = PointerMode::LValueReference;
1879 case dwarf::DW_TAG_rvalue_reference_type:
1880 PM = PointerMode::RValueReference;
1885 PO |= PointerOptions::Const;
1900 : PointerToMemberRepresentation::GeneralFunction;
1901 case DINode::FlagSingleInheritance:
1902 return PointerToMemberRepresentation::SingleInheritanceFunction;
1903 case DINode::FlagMultipleInheritance:
1904 return PointerToMemberRepresentation::MultipleInheritanceFunction;
1905 case DINode::FlagVirtualInheritance:
1906 return PointerToMemberRepresentation::VirtualInheritanceFunction;
1912 : PointerToMemberRepresentation::GeneralData;
1913 case DINode::FlagSingleInheritance:
1914 return PointerToMemberRepresentation::SingleInheritanceData;
1915 case DINode::FlagMultipleInheritance:
1916 return PointerToMemberRepresentation::MultipleInheritanceData;
1917 case DINode::FlagVirtualInheritance:
1918 return PointerToMemberRepresentation::VirtualInheritanceData;
1926 assert(Ty->
getTag() == dwarf::DW_TAG_ptr_to_member_type);
1927 bool IsPMF = isa<DISubroutineType>(Ty->getBaseType());
1928 TypeIndex ClassTI = getTypeIndex(Ty->getClassType());
1930 getTypeIndex(Ty->getBaseType(), IsPMF ? Ty->getClassType() :
nullptr);
1931 PointerKind PK = getPointerSizeInBytes() == 8 ? PointerKind::Near64
1932 : PointerKind::Near32;
1933 PointerMode PM = IsPMF ? PointerMode::PointerToMemberFunction
1934 : PointerMode::PointerToDataMember;
1948 case dwarf::DW_CC_normal:
return CallingConvention::NearC;
1949 case dwarf::DW_CC_BORLAND_msfastcall:
return CallingConvention::NearFast;
1950 case dwarf::DW_CC_BORLAND_thiscall:
return CallingConvention::ThisCall;
1951 case dwarf::DW_CC_BORLAND_stdcall:
return CallingConvention::NearStdCall;
1952 case dwarf::DW_CC_BORLAND_pascal:
return CallingConvention::NearPascal;
1953 case dwarf::DW_CC_LLVM_vectorcall:
return CallingConvention::NearVector;
1955 return CallingConvention::NearC;
1961 bool IsModifier =
true;
1962 const DIType *BaseTy = Ty;
1963 while (IsModifier && BaseTy) {
1965 switch (BaseTy->
getTag()) {
1966 case dwarf::DW_TAG_const_type:
1967 Mods |= ModifierOptions::Const;
1968 PO |= PointerOptions::Const;
1970 case dwarf::DW_TAG_volatile_type:
1971 Mods |= ModifierOptions::Volatile;
1972 PO |= PointerOptions::Volatile;
1974 case dwarf::DW_TAG_restrict_type:
1977 PO |= PointerOptions::Restrict;
1984 BaseTy = cast<DIDerivedType>(BaseTy)->getBaseType();
1992 switch (BaseTy->
getTag()) {
1993 case dwarf::DW_TAG_pointer_type:
1994 case dwarf::DW_TAG_reference_type:
1995 case dwarf::DW_TAG_rvalue_reference_type:
1996 return lowerTypePointer(cast<DIDerivedType>(BaseTy), PO);
1997 case dwarf::DW_TAG_ptr_to_member_type:
1998 return lowerTypeMemberPointer(cast<DIDerivedType>(BaseTy), PO);
2004 TypeIndex ModifiedTI = getTypeIndex(BaseTy);
2018 ReturnAndArgTypeIndices.push_back(getTypeIndex(ArgType));
2021 if (ReturnAndArgTypeIndices.size() > 1 &&
2022 ReturnAndArgTypeIndices.back() == TypeIndex::Void()) {
2025 TypeIndex ReturnTypeIndex = TypeIndex::Void();
2027 if (!ReturnAndArgTypeIndices.empty()) {
2028 auto ReturnAndArgTypesRef =
makeArrayRef(ReturnAndArgTypeIndices);
2029 ReturnTypeIndex = ReturnAndArgTypesRef.front();
2030 ArgTypeIndices = ReturnAndArgTypesRef.
drop_front();
2033 ArgListRecord ArgListRec(TypeRecordKind::ArgList, ArgTypeIndices);
2047 bool IsStaticMethod,
2050 TypeIndex ClassType = getTypeIndex(ClassTy);
2056 TypeIndex ReturnTypeIndex = TypeIndex::Void();
2058 ReturnTypeIndex = getTypeIndex(ReturnAndArgs[
Index++]);
2065 if (!IsStaticMethod && ReturnAndArgs.
size() >
Index) {
2067 dyn_cast_or_null<DIDerivedType>(ReturnAndArgs[
Index])) {
2068 if (PtrTy->getTag() == dwarf::DW_TAG_pointer_type) {
2069 ThisTypeIndex = getTypeIndexForThisPtr(PtrTy, Ty);
2076 ArgTypeIndices.push_back(getTypeIndex(ReturnAndArgs[
Index++]));
2079 if (!ArgTypeIndices.empty() && ArgTypeIndices.back() == TypeIndex::Void())
2082 ArgListRecord ArgListRec(TypeRecordKind::ArgList, ArgTypeIndices);
2088 ArgTypeIndices.size(), ArgListIndex, ThisAdjustment);
2093 unsigned VSlotCount =
2103 case DINode::FlagPrivate:
return MemberAccess::Private;
2104 case DINode::FlagPublic:
return MemberAccess::Public;
2105 case DINode::FlagProtected:
return MemberAccess::Protected;
2108 return RecordTag == dwarf::DW_TAG_class_type ? MemberAccess::Private
2109 : MemberAccess::Public;
2115 if (SP->isArtificial())
2116 return MethodOptions::CompilerGenerated;
2125 if (SP->getFlags() & DINode::FlagStaticMember)
2128 switch (SP->getVirtuality()) {
2129 case dwarf::DW_VIRTUALITY_none:
2131 case dwarf::DW_VIRTUALITY_virtual:
2132 return Introduced ? MethodKind::IntroducingVirtual : MethodKind::Virtual;
2133 case dwarf::DW_VIRTUALITY_pure_virtual:
2134 return Introduced ? MethodKind::PureIntroducingVirtual
2135 : MethodKind::PureVirtual;
2140 return MethodKind::Vanilla;
2145 case dwarf::DW_TAG_class_type:
2147 case dwarf::DW_TAG_structure_type:
2148 return TypeRecordKind::Struct;
2163 CO |= ClassOptions::HasUniqueName;
2169 if (ImmediateScope && isa<DICompositeType>(ImmediateScope))
2170 CO |= ClassOptions::Nested;
2176 if (Ty->
getTag() == dwarf::DW_TAG_enumeration_type) {
2177 if (ImmediateScope && isa<DISubprogram>(ImmediateScope))
2178 CO |= ClassOptions::Scoped;
2182 if (isa<DISubprogram>(
Scope)) {
2183 CO |= ClassOptions::Scoped;
2194 case dwarf::DW_TAG_class_type:
2195 case dwarf::DW_TAG_structure_type:
2196 case dwarf::DW_TAG_union_type:
2197 case dwarf::DW_TAG_enumeration_type:
2203 if (
const auto *File = Ty->
getFile()) {
2215 unsigned EnumeratorCount = 0;
2218 CO |= ClassOptions::ForwardReference;
2221 ContinuationBuilder.
begin(ContinuationRecordKind::FieldList);
2225 if (
auto *Enumerator = dyn_cast_or_null<DIEnumerator>(Element)) {
2237 std::string FullName = getFullyQualifiedName(Ty);
2243 addUDTSrcLine(Ty, EnumTI);
2277 void CodeViewDebug::clear() {
2278 assert(CurFn ==
nullptr);
2280 FnDebugInfo.clear();
2281 FileToFilepathMap.clear();
2284 TypeIndices.clear();
2285 CompleteTypeIndices.clear();
2286 ScopeGlobals.clear();
2287 CVGlobalVariableOffsets.clear();
2293 Info.Members.push_back({DDTy, 0});
2296 if ((DDTy->
getFlags() & DINode::FlagStaticMember) ==
2297 DINode::FlagStaticMember) {
2300 StaticConstMembers.push_back(DDTy);
2312 const DIType *Ty = DDTy->getBaseType();
2313 bool FullyResolved =
false;
2314 while (!FullyResolved) {
2316 case dwarf::DW_TAG_const_type:
2317 case dwarf::DW_TAG_volatile_type:
2320 Ty = cast<DIDerivedType>(Ty)->getBaseType();
2323 FullyResolved =
true;
2332 ClassInfo NestedInfo = collectClassInfo(DCTy);
2334 Info.Members.push_back(
2342 for (
auto *Element : Elements) {
2347 if (
auto *SP = dyn_cast<DISubprogram>(Element)) {
2348 Info.Methods[SP->getRawName()].push_back(SP);
2349 }
else if (
auto *DDTy = dyn_cast<DIDerivedType>(Element)) {
2350 if (DDTy->
getTag() == dwarf::DW_TAG_member) {
2351 collectMemberInfo(
Info, DDTy);
2352 }
else if (DDTy->
getTag() == dwarf::DW_TAG_inheritance) {
2353 Info.Inheritance.push_back(DDTy);
2354 }
else if (DDTy->
getTag() == dwarf::DW_TAG_pointer_type &&
2355 DDTy->
getName() ==
"__vtbl_ptr_type") {
2356 Info.VShapeTI = getTypeIndex(DDTy);
2357 }
else if (DDTy->
getTag() == dwarf::DW_TAG_typedef) {
2358 Info.NestedTypes.push_back(DDTy);
2359 }
else if (DDTy->
getTag() == dwarf::DW_TAG_friend) {
2363 }
else if (
auto *Composite = dyn_cast<DICompositeType>(Element)) {
2364 Info.NestedTypes.push_back(Composite);
2387 auto I = CompleteTypeIndices.find(Ty);
2388 if (
I != CompleteTypeIndices.end() &&
I->second ==
TypeIndex())
2390 return getCompleteTypeIndex(Ty);
2398 std::string FullName = getFullyQualifiedName(Ty);
2403 DeferredCompleteTypes.push_back(Ty);
2413 unsigned FieldCount;
2415 std::tie(FieldTI, VShapeTI, FieldCount, ContainsNestedClass) =
2416 lowerRecordFieldList(Ty);
2418 if (ContainsNestedClass)
2419 CO |= ClassOptions::ContainsNestedClass;
2427 CO |= ClassOptions::HasConstructorOrDestructor;
2429 std::string FullName = getFullyQualifiedName(Ty);
2437 addUDTSrcLine(Ty, ClassTI);
2447 return getCompleteTypeIndex(Ty);
2451 std::string FullName = getFullyQualifiedName(Ty);
2455 DeferredCompleteTypes.push_back(Ty);
2462 unsigned FieldCount;
2464 std::tie(FieldTI, std::ignore, FieldCount, ContainsNestedClass) =
2465 lowerRecordFieldList(Ty);
2467 if (ContainsNestedClass)
2468 CO |= ClassOptions::ContainsNestedClass;
2471 std::string FullName = getFullyQualifiedName(Ty);
2473 UnionRecord UR(FieldCount, CO, FieldTI, SizeInBytes, FullName,
2477 addUDTSrcLine(Ty, UnionTI);
2484 std::tuple<TypeIndex, TypeIndex, unsigned, bool>
2490 unsigned MemberCount = 0;
2493 ContinuationBuilder.
begin(ContinuationRecordKind::FieldList);
2497 if (
I->getFlags() & DINode::FlagVirtual) {
2499 unsigned VBPtrOffset =
I->getVBPtrOffset();
2501 unsigned VBTableIndex =
I->getOffsetInBits() / 4;
2502 auto RecordKind = (
I->getFlags() & DINode::FlagIndirectVirtualBase) == DINode::FlagIndirectVirtualBase
2503 ? TypeRecordKind::IndirectVirtualBaseClass
2504 : TypeRecordKind::VirtualBaseClass;
2507 getTypeIndex(
I->getBaseType()), getVBPTypeIndex(), VBPtrOffset,
2513 assert(
I->getOffsetInBits() % 8 == 0 &&
2514 "bases must be on byte boundaries");
2516 getTypeIndex(
I->getBaseType()),
2517 I->getOffsetInBits() / 8);
2531 if (
Member->isStaticMember()) {
2539 if ((
Member->getFlags() & DINode::FlagArtificial) &&
2540 Member->getName().startswith(
"_vptr$")) {
2550 if (
Member->isBitField()) {
2551 uint64_t StartBitOffset = MemberOffsetInBits;
2552 if (
const auto *CI =
2553 dyn_cast_or_null<ConstantInt>(
Member->getStorageOffsetInBits())) {
2554 MemberOffsetInBits = CI->getZExtValue() + MemberInfo.
BaseOffset;
2556 StartBitOffset -= MemberOffsetInBits;
2561 uint64_t MemberOffsetInBytes = MemberOffsetInBits / 8;
2569 for (
auto &MethodItr :
Info.Methods) {
2572 std::vector<OneMethodRecord> Methods;
2574 TypeIndex MethodType = getMemberFunctionType(SP, Ty);
2575 bool Introduced = SP->getFlags() & DINode::FlagIntroducedVirtual;
2577 unsigned VFTableOffset = -1;
2579 VFTableOffset = SP->getVirtualIndex() * getPointerSizeInBytes();
2587 assert(!Methods.empty() &&
"Empty methods map entry");
2588 if (Methods.size() == 1)
2602 for (
const DIType *Nested :
Info.NestedTypes) {
2609 return std::make_tuple(FieldTI,
Info.VShapeTI, MemberCount,
2610 !
Info.NestedTypes.empty());
2613 TypeIndex CodeViewDebug::getVBPTypeIndex() {
2619 PointerKind PK = getPointerSizeInBytes() == 8 ? PointerKind::Near64
2620 : PointerKind::Near32;
2623 PointerRecord PR(ModifiedTI, PK, PM, PO, getPointerSizeInBytes());
2633 return TypeIndex::Void();
2638 auto I = TypeIndices.find({Ty, ClassTy});
2639 if (
I != TypeIndices.end())
2642 TypeLoweringScope
S(*
this);
2644 return recordTypeIndexForDINode(Ty, TI, ClassTy);
2648 CodeViewDebug::getTypeIndexForThisPtr(
const DIDerivedType *PtrTy,
2650 assert(PtrTy->
getTag() == dwarf::DW_TAG_pointer_type &&
2651 "this type must be a pointer type");
2654 if (SubroutineTy->
getFlags() & DINode::DIFlags::FlagLValueReference)
2655 Options = PointerOptions::LValueRefThisPointer;
2656 else if (SubroutineTy->
getFlags() & DINode::DIFlags::FlagRValueReference)
2657 Options = PointerOptions::RValueRefThisPointer;
2664 auto I = TypeIndices.find({PtrTy, SubroutineTy});
2665 if (
I != TypeIndices.end())
2668 TypeLoweringScope
S(*
this);
2670 return recordTypeIndexForDINode(PtrTy, TI, SubroutineTy);
2673 TypeIndex CodeViewDebug::getTypeIndexForReferenceTo(
const DIType *Ty) {
2675 getPointerSizeInBytes() == 8 ? PointerKind::Near64
2676 : PointerKind::Near32,
2685 return TypeIndex::Void();
2690 if (Ty->
getTag() == dwarf::DW_TAG_typedef)
2691 (void)getTypeIndex(Ty);
2692 while (Ty->
getTag() == dwarf::DW_TAG_typedef)
2693 Ty = cast<DIDerivedType>(Ty)->getBaseType();
2698 case dwarf::DW_TAG_class_type:
2699 case dwarf::DW_TAG_structure_type:
2700 case dwarf::DW_TAG_union_type:
2703 return getTypeIndex(Ty);
2706 const auto *CTy = cast<DICompositeType>(Ty);
2708 TypeLoweringScope
S(*
this);
2714 if (!CTy->getName().empty() || !CTy->getIdentifier().empty()) {
2715 TypeIndex FwdDeclTI = getTypeIndex(CTy);
2720 if (CTy->isForwardDecl())
2727 auto InsertResult = CompleteTypeIndices.insert({CTy,
TypeIndex()});
2728 if (!InsertResult.second)
2729 return InsertResult.first->second;
2732 switch (CTy->getTag()) {
2733 case dwarf::DW_TAG_class_type:
2734 case dwarf::DW_TAG_structure_type:
2735 TI = lowerCompleteTypeClass(CTy);
2737 case dwarf::DW_TAG_union_type:
2738 TI = lowerCompleteTypeUnion(CTy);
2748 CompleteTypeIndices[CTy] = TI;
2756 void CodeViewDebug::emitDeferredCompleteTypes() {
2758 while (!DeferredCompleteTypes.empty()) {
2759 std::swap(DeferredCompleteTypes, TypesToEmit);
2761 getCompleteTypeIndex(RecordTy);
2762 TypesToEmit.clear();
2766 void CodeViewDebug::emitLocalVariableList(
const FunctionInfo &FI,
2770 for (
const LocalVariable &L : Locals)
2771 if (L.DIVar->isParameter())
2772 Params.push_back(&L);
2773 llvm::sort(Params, [](
const LocalVariable *L,
const LocalVariable *R) {
2774 return L->DIVar->getArg() <
R->DIVar->getArg();
2776 for (
const LocalVariable *L : Params)
2777 emitLocalVariable(FI, *L);
2780 for (
const LocalVariable &L : Locals)
2781 if (!L.DIVar->isParameter())
2782 emitLocalVariable(FI, L);
2785 void CodeViewDebug::emitLocalVariable(
const FunctionInfo &FI,
2786 const LocalVariable &Var) {
2788 MCSymbol *LocalEnd = beginSymbolRecord(SymbolKind::S_LOCAL);
2791 if (Var.DIVar->isParameter())
2792 Flags |= LocalSymFlags::IsParameter;
2793 if (Var.DefRanges.empty())
2794 Flags |= LocalSymFlags::IsOptimizedOut;
2798 ? getTypeIndexForReferenceTo(Var.DIVar->getType())
2799 : getCompleteTypeIndex(Var.DIVar->
getType());
2805 endSymbolRecord(LocalEnd);
2811 for (
const auto &Pair : Var.DefRanges) {
2812 LocalVarDef DefRange = Pair.first;
2813 const auto &Ranges = Pair.second;
2815 if (DefRange.InMemory) {
2816 int Offset = DefRange.DataOffset;
2817 unsigned Reg = DefRange.CVRegister;
2823 Reg = unsigned(RegisterId::VFRAME);
2824 Offset += FI.OffsetAdjustment;
2832 (
bool(Flags & LocalSymFlags::IsParameter)
2833 ? (EncFP == FI.EncodedParamFramePtrReg)
2834 : (EncFP == FI.EncodedLocalFramePtrReg))) {
2840 if (DefRange.IsSubfield) {
2841 RegRelFlags = DefRangeRegisterRelSym::IsSubfieldFlag |
2842 (DefRange.StructOffset
2843 << DefRangeRegisterRelSym::OffsetInParentShift);
2847 DRHdr.
Flags = RegRelFlags;
2852 assert(DefRange.DataOffset == 0 &&
"unexpected offset into register");
2853 if (DefRange.IsSubfield) {
2855 DRHdr.
Register = DefRange.CVRegister;
2861 DRHdr.
Register = DefRange.CVRegister;
2870 const FunctionInfo& FI) {
2871 for (LexicalBlock *Block : Blocks)
2872 emitLexicalBlock(*Block, FI);
2877 void CodeViewDebug::emitLexicalBlock(
const LexicalBlock &Block,
2878 const FunctionInfo& FI) {
2879 MCSymbol *RecordEnd = beginSymbolRecord(SymbolKind::S_BLOCK32);
2886 OS.
AddComment(
"Function section relative address");
2892 endSymbolRecord(RecordEnd);
2895 emitLocalVariableList(FI,
Block.Locals);
2896 emitGlobalVariableList(
Block.Globals);
2899 emitLexicalBlockList(
Block.Children, FI);
2902 emitEndSymbolRecord(SymbolKind::S_END);
2907 void CodeViewDebug::collectLexicalBlockInfo(
2913 collectLexicalBlockInfo(*
Scope, Blocks, Locals, Globals);
2918 void CodeViewDebug::collectLexicalBlockInfo(
2923 if (
Scope.isAbstractScope())
2928 bool IgnoreScope =
false;
2929 auto LI = ScopeVariables.find(&
Scope);
2931 LI != ScopeVariables.end() ? &LI->second :
nullptr;
2932 auto GI = ScopeGlobals.find(
Scope.getScopeNode());
2934 GI != ScopeGlobals.end() ? GI->second.get() :
nullptr;
2939 if (!Locals && !Globals)
2968 ParentGlobals.
append(Globals->begin(), Globals->end());
2969 collectLexicalBlockInfo(
Scope.getChildren(),
2979 auto BlockInsertion = CurFn->LexicalBlocks.insert({DILB, LexicalBlock()});
2980 if (!BlockInsertion.second)
2985 const InsnRange &Range = Ranges.front();
2986 assert(Range.first && Range.second);
2987 LexicalBlock &
Block = BlockInsertion.first->second;
2990 assert(
Block.Begin &&
"missing label for scope begin");
2991 assert(
Block.End &&
"missing label for scope end");
2997 ParentBlocks.push_back(&Block);
2998 collectLexicalBlockInfo(
Scope.getChildren(),
3006 assert(FnDebugInfo.count(&GV));
3007 assert(CurFn == FnDebugInfo[&GV].
get());
3013 collectLexicalBlockInfo(*CFS,
3021 ScopeVariables.clear();
3025 if (!CurFn->HaveLineInfo && !GV.
getSubprogram()->isThunk()) {
3026 FnDebugInfo.erase(&GV);
3032 for (
const auto &
MBB : *MF) {
3033 for (
const auto &
MI :
MBB) {
3034 if (
MDNode *MD =
MI.getHeapAllocMarker()) {
3037 dyn_cast<DIType>(MD)));
3042 CurFn->Annotations = MF->getCodeViewAnnotations();
3054 return DL &&
DL.getLine() != 0;
3061 if (!
Asm || !CurFn ||
MI->isDebugInstr() ||
3069 for (
const auto &NextMI : *
MI->getParent()) {
3070 if (NextMI.isDebugInstr())
3072 DL = NextMI.getDebugLoc();
3085 maybeRecordLocation(
DL,
Asm->
MF);
3098 void CodeViewDebug::endCVSubsection(
MCSymbol *EndLabel) {
3106 if (EE.Value == SymKind)
3123 void CodeViewDebug::endSymbolRecord(
MCSymbol *SymEnd) {
3132 void CodeViewDebug::emitEndSymbolRecord(
SymbolKind EndKind) {
3140 void CodeViewDebug::emitDebugInfoForUDTs(
3141 const std::vector<std::pair<std::string, const DIType *>> &UDTs) {
3143 size_t OriginalSize = UDTs.size();
3145 for (
const auto &UDT : UDTs) {
3148 MCSymbol *UDTRecordEnd = beginSymbolRecord(SymbolKind::S_UDT);
3150 OS.
emitInt32(getCompleteTypeIndex(
T).getIndex());
3151 assert(OriginalSize == UDTs.size() &&
3152 "getCompleteTypeIndex found new UDTs!");
3154 endSymbolRecord(UDTRecordEnd);
3158 void CodeViewDebug::collectGlobalVariableInfo() {
3163 GV.getDebugInfo(GVEs);
3164 for (
const auto *GVE : GVEs)
3165 GlobalMap[GVE] = &GV;
3170 const auto *
CU = cast<DICompileUnit>(Node);
3171 for (
const auto *GVE :
CU->getGlobalVariables()) {
3180 if ((
DIE->getNumElements() == 2) &&
3181 (
DIE->getElement(0) == dwarf::DW_OP_plus_uconst))
3186 CVGlobalVariableOffsets.insert(
3187 std::make_pair(DIGV,
DIE->getElement(1)));
3190 if (GlobalMap.
count(GVE) == 0 &&
DIE->isConstant()) {
3191 CVGlobalVariable CVGV = {DIGV,
DIE};
3195 const auto *GV = GlobalMap.
lookup(GVE);
3204 auto Insertion = ScopeGlobals.insert(
3205 {
Scope, std::unique_ptr<GlobalVariableList>()});
3206 if (Insertion.second)
3207 Insertion.first->second = std::make_unique<GlobalVariableList>();
3208 VariableList = Insertion.first->second.get();
3211 VariableList = &ComdatVariables;
3214 VariableList = &GlobalVariables;
3215 CVGlobalVariable CVGV = {DIGV, GV};
3221 void CodeViewDebug::collectDebugInfoForGlobals() {
3222 for (
const CVGlobalVariable &CVGV : GlobalVariables) {
3225 getCompleteTypeIndex(DIGV->
getType());
3229 for (
const CVGlobalVariable &CVGV : ComdatVariables) {
3232 getCompleteTypeIndex(DIGV->
getType());
3237 void CodeViewDebug::emitDebugInfoForGlobals() {
3241 switchToDebugSectionForSymbol(
nullptr);
3242 if (!GlobalVariables.empty() || !StaticConstMembers.empty()) {
3243 OS.
AddComment(
"Symbol subsection for globals");
3244 MCSymbol *EndLabel = beginCVSubsection(DebugSubsectionKind::Symbols);
3245 emitGlobalVariableList(GlobalVariables);
3246 emitStaticConstMemberList();
3247 endCVSubsection(EndLabel);
3252 for (
const CVGlobalVariable &CVGV : ComdatVariables) {
3257 switchToDebugSectionForSymbol(GVSym);
3258 MCSymbol *EndLabel = beginCVSubsection(DebugSubsectionKind::Symbols);
3260 emitDebugInfoForGlobal(CVGV);
3261 endCVSubsection(EndLabel);
3265 void CodeViewDebug::emitDebugInfoForRetainedTypes() {
3268 for (
auto *Ty : cast<DICompileUnit>(Node)->getRetainedTypes()) {
3269 if (
DIType *RT = dyn_cast<DIType>(Ty)) {
3279 for (
const CVGlobalVariable &CVGV : Globals) {
3281 emitDebugInfoForGlobal(CVGV);
3287 MCSymbol *SConstantEnd = beginSymbolRecord(SymbolKind::S_CONSTANT);
3289 OS.
emitInt32(getTypeIndex(DTy).getIndex());
3303 endSymbolRecord(SConstantEnd);
3306 void CodeViewDebug::emitStaticConstMemberList() {
3312 dyn_cast_or_null<ConstantInt>(DTy->getConstant()))
3316 dyn_cast_or_null<ConstantFP>(DTy->getConstant()))
3317 Value =
APSInt(CFP->getValueAPF().bitcastToAPInt(),
true);
3321 emitConstantSymbolRecord(DTy->getBaseType(),
Value,
3327 if (isa<DICompositeType>(Ty))
3330 if (
auto *DTy = dyn_cast<DIDerivedType>(Ty)) {
3332 if (
T == dwarf::DW_TAG_pointer_type ||
3333 T == dwarf::DW_TAG_ptr_to_member_type ||
3334 T == dwarf::DW_TAG_reference_type ||
3335 T == dwarf::DW_TAG_rvalue_reference_type)
3337 assert(DTy->getBaseType() &&
"Expected valid base type");
3341 auto *BTy = cast<DIBasicType>(Ty);
3342 return (BTy->getEncoding() == dwarf::DW_ATE_float);
3345 void CodeViewDebug::emitDebugInfoForGlobal(
const CVGlobalVariable &CVGV) {
3350 if (
const auto *MemberDecl = dyn_cast_or_null<DIDerivedType>(
3352 Scope = MemberDecl->getScope();
3366 : SymbolKind::S_GTHREAD32)
3368 : SymbolKind::S_GDATA32);
3375 if (CVGlobalVariableOffsets.find(DIGV) != CVGlobalVariableOffsets.end())
3377 Offset = CVGlobalVariableOffsets[DIGV];
3383 const unsigned LengthOfDataRecord = 12;
3385 endSymbolRecord(DataEnd);
3389 "Global constant variables must contain a constant expression.");