41 #include "llvm/Config/llvm-config.h" 97 case Triple::ArchType::x86:
99 case Triple::ArchType::x86_64:
101 case Triple::ArchType::thumb:
103 case Triple::ArchType::aarch64:
126 collectGlobalVariableInfo();
129 ConstantInt *GH = mdconst::extract_or_null<ConstantInt>(
131 EmitDebugGlobalHashes = GH && !GH->
isZero();
135 std::string &Filepath = FileToFilepathMap[
File];
136 if (!Filepath.empty())
143 if (Dir.
startswith(
"/") || Filename.startswith(
"/")) {
147 if (Dir.
back() !=
'/')
149 Filepath += Filename;
157 if (Filename.find(
':') == 1)
160 Filepath = (Dir +
"\\" + Filename).str();
165 std::replace(Filepath.begin(), Filepath.end(),
'/',
'\\');
169 while ((Cursor = Filepath.find(
"\\.\\", Cursor)) != std::string::npos)
170 Filepath.erase(Cursor, 2);
175 while ((Cursor = Filepath.find(
"\\..\\", Cursor)) != std::string::npos) {
180 size_t PrevSlash = Filepath.rfind(
'\\', Cursor - 1);
181 if (PrevSlash == std::string::npos)
185 Filepath.erase(PrevSlash, Cursor + 3 - PrevSlash);
192 while ((Cursor = Filepath.find(
"\\\\", Cursor)) != std::string::npos)
193 Filepath.erase(Cursor, 1);
198 unsigned CodeViewDebug::maybeRecordFile(
const DIFile *
F) {
200 unsigned NextId = FileIdMap.size() + 1;
201 auto Insertion = FileIdMap.insert(std::make_pair(FullPath, NextId));
202 if (Insertion.second) {
206 if (F->getChecksum()) {
207 std::string Checksum =
fromHex(F->getChecksum()->Value);
209 memcpy(CKMem, Checksum.data(), Checksum.size());
211 reinterpret_cast<const uint8_t *
>(CKMem), Checksum.size());
212 switch (F->getChecksum()->Kind) {
218 static_cast<unsigned>(CSKind));
220 assert(Success &&
".cv_file directive failed");
222 return Insertion.first->second;
225 CodeViewDebug::InlineSite &
226 CodeViewDebug::getInlineSite(
const DILocation *InlinedAt,
228 auto SiteInsertion = CurFn->InlineSites.insert({InlinedAt, InlineSite()});
229 InlineSite *Site = &SiteInsertion.first->second;
230 if (SiteInsertion.second) {
231 unsigned ParentFuncId = CurFn->FuncId;
232 if (
const DILocation *OuterIA = InlinedAt->getInlinedAt())
234 getInlineSite(OuterIA, InlinedAt->getScope()->getSubprogram())
237 Site->SiteFuncId = NextFuncId++;
239 Site->SiteFuncId, ParentFuncId, maybeRecordFile(InlinedAt->getFile()),
240 InlinedAt->getLine(), InlinedAt->getColumn(),
SMLoc());
241 Site->Inlinee = Inlinee;
242 InlinedSubprograms.insert(Inlinee);
243 getFuncIdForSubprogram(Inlinee);
250 if (!ScopeName.
empty())
253 switch (Scope->
getTag()) {
254 case dwarf::DW_TAG_enumeration_type:
255 case dwarf::DW_TAG_class_type:
256 case dwarf::DW_TAG_structure_type:
257 case dwarf::DW_TAG_union_type:
258 return "<unnamed-tag>";
259 case dwarf::DW_TAG_namespace:
260 return "`anonymous namespace'";
269 while (Scope !=
nullptr) {
270 if (ClosestSubprogram ==
nullptr)
273 if (!ScopeName.empty())
274 QualifiedNameComponents.
push_back(ScopeName);
277 return ClosestSubprogram;
282 std::string FullyQualifiedName;
285 FullyQualifiedName.append(QualifiedNameComponent);
286 FullyQualifiedName.append(
"::");
288 FullyQualifiedName.append(TypeName);
289 return FullyQualifiedName;
303 if (CVD.TypeEmissionLevel == 1)
304 CVD.emitDeferredCompleteTypes();
305 --CVD.TypeEmissionLevel;
317 if (!Scope || isa<DIFile>(Scope))
320 assert(!isa<DIType>(Scope) &&
"shouldn't make a namespace scope for a type");
323 auto I = TypeIndices.find({Scope,
nullptr});
324 if (
I != TypeIndices.end())
330 auto TI = TypeTable.writeLeafType(SID);
331 return recordTypeIndexForDINode(Scope, TI);
338 auto I = TypeIndices.find({SP,
nullptr});
339 if (
I != TypeIndices.end())
348 if (
const auto *Class = dyn_cast_or_null<DICompositeType>(Scope)) {
352 TypeIndex ClassType = getTypeIndex(Class);
355 TI = TypeTable.writeLeafType(MFuncId);
358 TypeIndex ParentScope = getScopeIndex(Scope);
360 TI = TypeTable.writeLeafType(FuncId);
363 return recordTypeIndexForDINode(SP, TI);
367 return ((DCTy->
getFlags() & DINode::FlagTrivial) == DINode::FlagTrivial);
375 const DIType *ReturnTy =
nullptr;
377 if (TypeArray.size())
378 ReturnTy = TypeArray[0].resolve();
381 if (
auto *ReturnDCTy = dyn_cast_or_null<DICompositeType>(ReturnTy)) {
383 FO |= FunctionOptions::CxxReturnUdt;
387 if (ClassTy && !
isTrivial(ClassTy) && SPName == ClassTy->getName()) {
388 FO |= FunctionOptions::Constructor;
400 if (SP->getDeclaration())
401 SP = SP->getDeclaration();
402 assert(!SP->getDeclaration() &&
"should use declaration as key");
406 auto I = TypeIndices.find({SP, Class});
407 if (I != TypeIndices.end())
413 TypeLoweringScope S(*
this);
414 const bool IsStaticMethod = (SP->getFlags() & DINode::FlagStaticMember) != 0;
418 SP->getType(), Class, SP->getThisAdjustment(), IsStaticMethod, FO);
419 return recordTypeIndexForDINode(SP, TI, Class);
425 auto InsertResult = TypeIndices.insert({{Node, ClassTy}, TI});
427 assert(InsertResult.second &&
"DINode was already assigned a type index");
431 unsigned CodeViewDebug::getPointerSizeInBytes() {
435 void CodeViewDebug::recordLocalVariable(LocalVariable &&Var,
440 InlineSite &Site = getInlineSite(InlinedAt, Inlinee);
441 Site.InlinedLocals.emplace_back(Var);
444 ScopeVariables[
LS].emplace_back(Var);
455 void CodeViewDebug::maybeRecordLocation(
const DebugLoc &DL,
467 if (LI.getStartLine() != DL.
getLine() || LI.isAlwaysStepInto() ||
468 LI.isNeverStepInto())
472 if (CI.getStartColumn() != DL.
getCol())
475 if (!CurFn->HaveLineInfo)
476 CurFn->HaveLineInfo =
true;
479 FileId = CurFn->LastFileId;
481 FileId = CurFn->LastFileId = maybeRecordFile(DL->getFile());
484 unsigned FuncId = CurFn->FuncId;
485 if (
const DILocation *SiteLoc = DL->getInlinedAt()) {
491 getInlineSite(SiteLoc, Loc->getScope()->getSubprogram()).SiteFuncId;
494 bool FirstLoc =
true;
495 while ((SiteLoc = Loc->getInlinedAt())) {
497 getInlineSite(SiteLoc, Loc->getScope()->getSubprogram());
506 OS.EmitCVLocDirective(FuncId, FileId, DL.
getLine(), DL.
getCol(),
508 DL->getFilename(),
SMLoc());
511 void CodeViewDebug::emitCodeViewMagicVersion() {
512 OS.EmitValueToAlignment(4);
513 OS.AddComment(
"Debug section magic");
530 switchToDebugSectionForSymbol(
nullptr);
532 MCSymbol *CompilerInfo = beginCVSubsection(DebugSubsectionKind::Symbols);
533 emitCompilerInformation();
534 endCVSubsection(CompilerInfo);
536 emitInlineeLinesSubsection();
539 for (
auto &
P : FnDebugInfo)
540 if (!
P.first->isDeclarationForLinker())
541 emitDebugInfoForFunction(
P.first, *
P.second);
544 setCurrentSubprogram(
nullptr);
545 emitDebugInfoForGlobals();
548 emitDebugInfoForRetainedTypes();
552 switchToDebugSectionForSymbol(
nullptr);
555 if (!GlobalUDTs.empty()) {
556 MCSymbol *SymbolsEnd = beginCVSubsection(DebugSubsectionKind::Symbols);
557 emitDebugInfoForUDTs(GlobalUDTs);
558 endCVSubsection(SymbolsEnd);
562 OS.AddComment(
"File index to string table offset subsection");
563 OS.EmitCVFileChecksumsDirective();
566 OS.AddComment(
"String table");
567 OS.EmitCVStringTableDirective();
576 emitTypeInformation();
578 if (EmitDebugGlobalHashes)
579 emitTypeGlobalHashes();
585 unsigned MaxFixedRecordLength = 0xF00) {
596 void CodeViewDebug::emitTypeInformation() {
597 if (TypeTable.empty())
602 emitCodeViewMagicVersion();
605 if (OS.isVerboseAsm()) {
606 CommentPrefix +=
'\t';
608 CommentPrefix +=
' ';
617 if (OS.isVerboseAsm()) {
636 OS.EmitBinaryData(Record.
str_data());
637 B = Table.getNext(*B);
641 void CodeViewDebug::emitTypeGlobalHashes() {
642 if (TypeTable.empty())
649 OS.EmitValueToAlignment(4);
650 OS.AddComment(
"Magic");
652 OS.AddComment(
"Section Version");
653 OS.EmitIntValue(0, 2);
654 OS.AddComment(
"Hash Algorithm");
655 OS.EmitIntValue(uint16_t(GlobalTypeHashAlg::SHA1_8), 2);
657 TypeIndex TI(TypeIndex::FirstNonSimpleIndex);
658 for (
const auto &GHR : TypeTable.hashes()) {
659 if (OS.isVerboseAsm()) {
665 OS.AddComment(Comment);
668 assert(GHR.Hash.size() == 8);
669 StringRef S(reinterpret_cast<const char *>(GHR.Hash.data()),
671 OS.EmitBinaryData(S);
677 case dwarf::DW_LANG_C:
678 case dwarf::DW_LANG_C89:
679 case dwarf::DW_LANG_C99:
680 case dwarf::DW_LANG_C11:
681 case dwarf::DW_LANG_ObjC:
683 case dwarf::DW_LANG_C_plus_plus:
684 case dwarf::DW_LANG_C_plus_plus_03:
685 case dwarf::DW_LANG_C_plus_plus_11:
686 case dwarf::DW_LANG_C_plus_plus_14:
688 case dwarf::DW_LANG_Fortran77:
689 case dwarf::DW_LANG_Fortran90:
690 case dwarf::DW_LANG_Fortran03:
691 case dwarf::DW_LANG_Fortran08:
693 case dwarf::DW_LANG_Pascal83:
695 case dwarf::DW_LANG_Cobol74:
696 case dwarf::DW_LANG_Cobol85:
698 case dwarf::DW_LANG_Java:
700 case dwarf::DW_LANG_D:
721 for (
const char C : Name) {
724 V.Part[
N] +=
C -
'0';
725 }
else if (
C ==
'.') {
735 void CodeViewDebug::emitCompilerInformation() {
736 MCSymbol *CompilerEnd = beginSymbolRecord(SymbolKind::S_COMPILE3);
741 const auto *
CU = cast<DICompileUnit>(Node);
747 OS.AddComment(
"Flags and language");
748 OS.EmitIntValue(Flags, 4);
750 OS.AddComment(
"CPUType");
751 OS.EmitIntValue(static_cast<uint64_t>(TheCPU), 2);
755 OS.AddComment(
"Frontend version");
756 for (
int N = 0;
N < 4; ++
N)
757 OS.EmitIntValue(FrontVer.Part[
N], 2);
762 int Major = 1000 * LLVM_VERSION_MAJOR +
763 10 * LLVM_VERSION_MINOR +
767 Version BackVer = {{ Major, 0, 0, 0 }};
768 OS.AddComment(
"Backend version");
769 for (
int N = 0;
N < 4; ++
N)
770 OS.EmitIntValue(BackVer.Part[
N], 2);
772 OS.AddComment(
"Null-terminated compiler version string");
775 endSymbolRecord(CompilerEnd);
784 void CodeViewDebug::emitBuildInfo() {
795 TypeIndex BuildInfoArgs[BuildInfoRecord::MaxArgs] = {};
798 const auto *
CU = cast<DICompileUnit>(Node);
799 const DIFile *MainSourceFile =
CU->getFile();
800 BuildInfoArgs[BuildInfoRecord::CurrentDirectory] =
802 BuildInfoArgs[BuildInfoRecord::SourceFile] =
807 TypeIndex BuildInfoIndex = TypeTable.writeLeafType(BIR);
811 MCSymbol *BISubsecEnd = beginCVSubsection(DebugSubsectionKind::Symbols);
812 MCSymbol *BIEnd = beginSymbolRecord(SymbolKind::S_BUILDINFO);
813 OS.AddComment(
"LF_BUILDINFO index");
814 OS.EmitIntValue(BuildInfoIndex.
getIndex(), 4);
815 endSymbolRecord(BIEnd);
816 endCVSubsection(BISubsecEnd);
819 void CodeViewDebug::emitInlineeLinesSubsection() {
820 if (InlinedSubprograms.empty())
823 OS.AddComment(
"Inlinee lines subsection");
824 MCSymbol *InlineEnd = beginCVSubsection(DebugSubsectionKind::InlineeLines);
830 OS.AddComment(
"Inlinee lines signature");
831 OS.EmitIntValue(
unsigned(InlineeLinesSignature::Normal), 4);
834 assert(TypeIndices.count({SP, nullptr}));
835 TypeIndex InlineeIdx = TypeIndices[{SP,
nullptr}];
838 unsigned FileId = maybeRecordFile(SP->
getFile());
839 OS.AddComment(
"Inlined function " + SP->
getName() +
" starts at " +
842 OS.AddComment(
"Type index of inlined function");
843 OS.EmitIntValue(InlineeIdx.getIndex(), 4);
844 OS.AddComment(
"Offset into filechecksum table");
845 OS.EmitCVFileChecksumOffsetDirective(FileId);
846 OS.AddComment(
"Starting line number");
847 OS.EmitIntValue(SP->getLine(), 4);
850 endCVSubsection(InlineEnd);
853 void CodeViewDebug::emitInlinedCallSite(
const FunctionInfo &FI,
855 const InlineSite &Site) {
856 assert(TypeIndices.count({Site.Inlinee, nullptr}));
857 TypeIndex InlineeIdx = TypeIndices[{Site.Inlinee,
nullptr}];
860 MCSymbol *InlineEnd = beginSymbolRecord(SymbolKind::S_INLINESITE);
862 OS.AddComment(
"PtrParent");
863 OS.EmitIntValue(0, 4);
864 OS.AddComment(
"PtrEnd");
865 OS.EmitIntValue(0, 4);
866 OS.AddComment(
"Inlinee type index");
867 OS.EmitIntValue(InlineeIdx.getIndex(), 4);
869 unsigned FileId = maybeRecordFile(Site.Inlinee->getFile());
870 unsigned StartLineNum = Site.Inlinee->getLine();
872 OS.EmitCVInlineLinetableDirective(Site.SiteFuncId, FileId, StartLineNum,
875 endSymbolRecord(InlineEnd);
877 emitLocalVariableList(FI, Site.InlinedLocals);
880 for (
const DILocation *ChildSite : Site.ChildSites) {
881 auto I = FI.InlineSites.find(ChildSite);
882 assert(
I != FI.InlineSites.end() &&
883 "child site not in function inline site map");
884 emitInlinedCallSite(FI, ChildSite,
I->second);
888 emitEndSymbolRecord(SymbolKind::S_INLINESITE_END);
891 void CodeViewDebug::switchToDebugSectionForSymbol(
const MCSymbol *GVSym) {
901 DebugSec = OS.getContext().getAssociativeCOFFSection(DebugSec, KeySym);
903 OS.SwitchSection(DebugSec);
907 if (ComdatDebugSections.insert(DebugSec).second)
908 emitCodeViewMagicVersion();
913 void CodeViewDebug::emitDebugInfoForThunk(
const Function *GV,
919 OS.AddComment(
"Symbol subsection for " +
Twine(FuncName));
920 MCSymbol *SymbolsEnd = beginCVSubsection(DebugSubsectionKind::Symbols);
923 MCSymbol *ThunkRecordEnd = beginSymbolRecord(SymbolKind::S_THUNK32);
924 OS.AddComment(
"PtrParent");
925 OS.EmitIntValue(0, 4);
926 OS.AddComment(
"PtrEnd");
927 OS.EmitIntValue(0, 4);
928 OS.AddComment(
"PtrNext");
929 OS.EmitIntValue(0, 4);
930 OS.AddComment(
"Thunk section relative address");
931 OS.EmitCOFFSecRel32(Fn, 0);
932 OS.AddComment(
"Thunk section index");
933 OS.EmitCOFFSectionIndex(Fn);
934 OS.AddComment(
"Code size");
935 OS.emitAbsoluteSymbolDiff(FI.End, Fn, 2);
936 OS.AddComment(
"Ordinal");
937 OS.EmitIntValue(
unsigned(ordinal), 1);
938 OS.AddComment(
"Function name");
941 endSymbolRecord(ThunkRecordEnd);
947 emitEndSymbolRecord(SymbolKind::S_PROC_ID_END);
949 endCVSubsection(SymbolsEnd);
952 void CodeViewDebug::emitDebugInfoForFunction(
const Function *GV,
960 switchToDebugSectionForSymbol(Fn);
962 std::string FuncName;
965 setCurrentSubprogram(SP);
968 emitDebugInfoForThunk(GV, FI, Fn);
979 if (FuncName.empty())
984 OS.EmitCVFPOData(Fn);
987 OS.AddComment(
"Symbol subsection for " +
Twine(FuncName));
988 MCSymbol *SymbolsEnd = beginCVSubsection(DebugSubsectionKind::Symbols);
991 : SymbolKind::S_GPROC32_ID;
992 MCSymbol *ProcRecordEnd = beginSymbolRecord(ProcKind);
995 OS.AddComment(
"PtrParent");
996 OS.EmitIntValue(0, 4);
997 OS.AddComment(
"PtrEnd");
998 OS.EmitIntValue(0, 4);
999 OS.AddComment(
"PtrNext");
1000 OS.EmitIntValue(0, 4);
1003 OS.AddComment(
"Code size");
1004 OS.emitAbsoluteSymbolDiff(FI.End, Fn, 4);
1005 OS.AddComment(
"Offset after prologue");
1006 OS.EmitIntValue(0, 4);
1007 OS.AddComment(
"Offset before epilogue");
1008 OS.EmitIntValue(0, 4);
1009 OS.AddComment(
"Function type index");
1010 OS.EmitIntValue(getFuncIdForSubprogram(GV->
getSubprogram()).getIndex(), 4);
1011 OS.AddComment(
"Function section relative address");
1012 OS.EmitCOFFSecRel32(Fn, 0);
1013 OS.AddComment(
"Function section index");
1014 OS.EmitCOFFSectionIndex(Fn);
1015 OS.AddComment(
"Flags");
1016 OS.EmitIntValue(0, 1);
1018 OS.AddComment(
"Function name");
1021 endSymbolRecord(ProcRecordEnd);
1023 MCSymbol *FrameProcEnd = beginSymbolRecord(SymbolKind::S_FRAMEPROC);
1025 OS.AddComment(
"FrameSize");
1026 OS.EmitIntValue(FI.FrameSize - FI.CSRSize, 4);
1027 OS.AddComment(
"Padding");
1028 OS.EmitIntValue(0, 4);
1029 OS.AddComment(
"Offset of padding");
1030 OS.EmitIntValue(0, 4);
1031 OS.AddComment(
"Bytes of callee saved registers");
1032 OS.EmitIntValue(FI.CSRSize, 4);
1033 OS.AddComment(
"Exception handler offset");
1034 OS.EmitIntValue(0, 4);
1035 OS.AddComment(
"Exception handler section");
1036 OS.EmitIntValue(0, 2);
1037 OS.AddComment(
"Flags (defines frame register)");
1038 OS.EmitIntValue(
uint32_t(FI.FrameProcOpts), 4);
1039 endSymbolRecord(FrameProcEnd);
1041 emitLocalVariableList(FI, FI.Locals);
1042 emitGlobalVariableList(FI.Globals);
1043 emitLexicalBlockList(FI.ChildBlocks, FI);
1048 for (
const DILocation *InlinedAt : FI.ChildSites) {
1049 auto I = FI.InlineSites.find(InlinedAt);
1050 assert(
I != FI.InlineSites.end() &&
1051 "child site not in function inline site map");
1052 emitInlinedCallSite(FI, InlinedAt,
I->second);
1055 for (
auto Annot : FI.Annotations) {
1057 MDTuple *Strs = cast<MDTuple>(Annot.second);
1058 MCSymbol *AnnotEnd = beginSymbolRecord(SymbolKind::S_ANNOTATION);
1059 OS.EmitCOFFSecRel32(Label, 0);
1061 OS.EmitCOFFSectionIndex(Label);
1066 StringRef Str = cast<MDString>(MD)->getString();
1067 assert(Str.
data()[Str.
size()] ==
'\0' &&
"non-nullterminated MDString");
1070 endSymbolRecord(AnnotEnd);
1074 emitDebugInfoForUDTs(LocalUDTs);
1077 emitEndSymbolRecord(SymbolKind::S_PROC_ID_END);
1079 endCVSubsection(SymbolsEnd);
1082 OS.EmitCVLinetableDirective(FI.FuncId, Fn, FI.End);
1085 CodeViewDebug::LocalVarDefRange
1086 CodeViewDebug::createDefRangeMem(uint16_t CVRegister,
int Offset) {
1087 LocalVarDefRange DR;
1090 assert(DR.DataOffset == Offset &&
"truncation");
1092 DR.StructOffset = 0;
1093 DR.CVRegister = CVRegister;
1097 void CodeViewDebug::collectVariableInfoFromMFTable(
1107 assert(
VI.Var->isValidLocationForIntrinsic(
VI.Loc) &&
1108 "Expected inlined-at fields to agree");
1110 Processed.
insert(InlinedEntity(
VI.Var,
VI.Loc->getInlinedAt()));
1119 int64_t ExprOffset = 0;
1121 if (!
VI.Expr->extractIfOffset(ExprOffset))
1125 unsigned FrameReg = 0;
1130 LocalVarDefRange DefRange =
1131 createDefRangeMem(CVReg, FrameOffset + ExprOffset);
1136 DefRange.Ranges.emplace_back(Begin, End);
1141 Var.DefRanges.emplace_back(std::move(DefRange));
1142 recordLocalVariable(std::move(Var), Scope);
1154 void CodeViewDebug::calculateRanges(
1159 for (
auto I = Ranges.
begin(),
E = Ranges.
end();
I !=
E; ++
I) {
1177 if (Var.UseReferenceType) {
1180 Location->LoadChain.pop_back();
1186 Var.UseReferenceType =
true;
1187 Var.DefRanges.clear();
1188 calculateRanges(Var, Ranges);
1193 if (Location->Register == 0 || Location->LoadChain.size() > 1)
1196 LocalVarDefRange DR;
1198 DR.InMemory = !Location->LoadChain.empty();
1200 !Location->LoadChain.empty() ? Location->LoadChain.back() : 0;
1201 if (Location->FragmentInfo) {
1202 DR.IsSubfield =
true;
1203 DR.StructOffset = Location->FragmentInfo->OffsetInBits / 8;
1205 DR.IsSubfield =
false;
1206 DR.StructOffset = 0;
1209 if (Var.DefRanges.empty() ||
1210 Var.DefRanges.back().isDifferentLocation(DR)) {
1211 Var.DefRanges.emplace_back(std::move(DR));
1221 auto J = std::next(
I);
1235 Var.DefRanges.back().Ranges;
1236 if (!R.
empty() && R.
back().second == Begin)
1237 R.
back().second = End;
1245 void CodeViewDebug::collectVariableInfo(
const DISubprogram *SP) {
1248 collectVariableInfoFromMFTable(Processed);
1251 InlinedEntity IV =
I.first;
1252 if (Processed.
count(IV))
1258 const auto &Ranges =
I.second;
1272 calculateRanges(Var, Ranges);
1273 recordLocalVariable(std::move(Var), Scope);
1282 auto Insertion = FnDebugInfo.insert({&GV, llvm::make_unique<FunctionInfo>()});
1283 assert(Insertion.second &&
"function already has info");
1284 CurFn = Insertion.first->second.get();
1285 CurFn->FuncId = NextFuncId++;
1300 if (CurFn->FrameSize > 0) {
1302 CurFn->EncodedLocalFramePtrReg = EncodedFramePtrReg::StackPtr;
1303 CurFn->EncodedParamFramePtrReg = EncodedFramePtrReg::StackPtr;
1307 if (CurFn->HasStackRealignment) {
1309 CurFn->EncodedLocalFramePtrReg = EncodedFramePtrReg::StackPtr;
1321 FPO |= FrameProcedureOptions::HasAlloca;
1323 FPO |= FrameProcedureOptions::HasSetJmp;
1326 FPO |= FrameProcedureOptions::HasInlineAssembly;
1330 FPO |= FrameProcedureOptions::HasStructuredExceptionHandling;
1332 FPO |= FrameProcedureOptions::HasExceptionHandling;
1335 FPO |= FrameProcedureOptions::MarkedInline;
1337 FPO |= FrameProcedureOptions::Naked;
1339 FPO |= FrameProcedureOptions::SecurityChecks;
1344 FPO |= FrameProcedureOptions::OptimizedForSpeed;
1346 CurFn->FrameProcOpts = FPO;
1348 OS.EmitCVFuncIdDirective(CurFn->FuncId);
1355 bool EmptyPrologue =
true;
1356 for (
const auto &MBB : *MF) {
1357 for (
const auto &
MI : MBB) {
1360 PrologEndLoc =
MI.getDebugLoc();
1362 }
else if (!
MI.isMetaInstruction()) {
1363 EmptyPrologue =
false;
1369 if (PrologEndLoc && !EmptyPrologue) {
1371 maybeRecordLocation(FnStartDL, MF);
1380 if (T->
getTag() == dwarf::DW_TAG_typedef) {
1382 switch (Scope->
getTag()) {
1383 case dwarf::DW_TAG_structure_type:
1384 case dwarf::DW_TAG_class_type:
1385 case dwarf::DW_TAG_union_type:
1398 T = DT->getBaseType().
resolve();
1403 void CodeViewDebug::addToUDTs(
const DIType *Ty) {
1414 std::string FullyQualifiedName =
1417 if (ClosestSubprogram ==
nullptr) {
1418 GlobalUDTs.emplace_back(std::move(FullyQualifiedName), Ty);
1419 }
else if (ClosestSubprogram == CurrentSubprogram) {
1420 LocalUDTs.emplace_back(std::move(FullyQualifiedName), Ty);
1434 case dwarf::DW_TAG_array_type:
1435 return lowerTypeArray(cast<DICompositeType>(Ty));
1436 case dwarf::DW_TAG_typedef:
1437 return lowerTypeAlias(cast<DIDerivedType>(Ty));
1438 case dwarf::DW_TAG_base_type:
1439 return lowerTypeBasic(cast<DIBasicType>(Ty));
1440 case dwarf::DW_TAG_pointer_type:
1441 if (cast<DIDerivedType>(Ty)->
getName() ==
"__vtbl_ptr_type")
1442 return lowerTypeVFTableShape(cast<DIDerivedType>(Ty));
1444 case dwarf::DW_TAG_reference_type:
1445 case dwarf::DW_TAG_rvalue_reference_type:
1446 return lowerTypePointer(cast<DIDerivedType>(Ty));
1447 case dwarf::DW_TAG_ptr_to_member_type:
1448 return lowerTypeMemberPointer(cast<DIDerivedType>(Ty));
1449 case dwarf::DW_TAG_restrict_type:
1450 case dwarf::DW_TAG_const_type:
1451 case dwarf::DW_TAG_volatile_type:
1453 return lowerTypeModifier(cast<DIDerivedType>(Ty));
1454 case dwarf::DW_TAG_subroutine_type:
1458 return lowerTypeMemberFunction(cast<DISubroutineType>(Ty), ClassTy,
1462 return lowerTypeFunction(cast<DISubroutineType>(Ty));
1463 case dwarf::DW_TAG_enumeration_type:
1464 return lowerTypeEnum(cast<DICompositeType>(Ty));
1465 case dwarf::DW_TAG_class_type:
1466 case dwarf::DW_TAG_structure_type:
1467 return lowerTypeClass(cast<DICompositeType>(Ty));
1468 case dwarf::DW_TAG_union_type:
1469 return lowerTypeUnion(cast<DICompositeType>(Ty));
1470 case dwarf::DW_TAG_unspecified_type:
1471 if (Ty->
getName() ==
"decltype(nullptr)")
1472 return TypeIndex::NullptrT();
1481 DITypeRef UnderlyingTypeRef = Ty->getBaseType();
1482 TypeIndex UnderlyingTypeIndex = getTypeIndex(UnderlyingTypeRef);
1487 if (UnderlyingTypeIndex ==
TypeIndex(SimpleTypeKind::Int32Long) &&
1488 TypeName ==
"HRESULT")
1489 return TypeIndex(SimpleTypeKind::HResult);
1490 if (UnderlyingTypeIndex ==
TypeIndex(SimpleTypeKind::UInt16Short) &&
1491 TypeName ==
"wchar_t")
1492 return TypeIndex(SimpleTypeKind::WideCharacter);
1494 return UnderlyingTypeIndex;
1499 TypeIndex ElementTypeIndex = getTypeIndex(ElementTypeRef);
1501 TypeIndex IndexType = getPointerSizeInBytes() == 8
1503 :
TypeIndex(SimpleTypeKind::UInt32Long);
1509 for (
int i = Elements.size() - 1; i >= 0; --i) {
1510 const DINode *Element = Elements[i];
1511 assert(Element->
getTag() == dwarf::DW_TAG_subrange_type);
1513 const DISubrange *Subrange = cast<DISubrange>(Element);
1514 assert(Subrange->getLowerBound() == 0 &&
1515 "codeview doesn't support subranges with lower bounds");
1517 if (
auto *CI = Subrange->getCount().dyn_cast<
ConstantInt*>())
1518 Count = CI->getSExtValue();
1528 ElementSize *= Count;
1532 uint64_t ArraySize =
1533 (i == 0 && ElementSize == 0) ? Ty->
getSizeInBits() / 8 : ElementSize;
1536 ArrayRecord AR(ElementTypeIndex, IndexType, ArraySize, Name);
1537 ElementTypeIndex = TypeTable.writeLeafType(AR);
1540 return ElementTypeIndex;
1553 case dwarf::DW_ATE_address:
1556 case dwarf::DW_ATE_boolean:
1558 case 1: STK = SimpleTypeKind::Boolean8;
break;
1559 case 2: STK = SimpleTypeKind::Boolean16;
break;
1560 case 4: STK = SimpleTypeKind::Boolean32;
break;
1561 case 8: STK = SimpleTypeKind::Boolean64;
break;
1562 case 16: STK = SimpleTypeKind::Boolean128;
break;
1565 case dwarf::DW_ATE_complex_float:
1567 case 2: STK = SimpleTypeKind::Complex16;
break;
1568 case 4: STK = SimpleTypeKind::Complex32;
break;
1569 case 8: STK = SimpleTypeKind::Complex64;
break;
1570 case 10: STK = SimpleTypeKind::Complex80;
break;
1571 case 16: STK = SimpleTypeKind::Complex128;
break;
1574 case dwarf::DW_ATE_float:
1576 case 2: STK = SimpleTypeKind::Float16;
break;
1577 case 4: STK = SimpleTypeKind::Float32;
break;
1578 case 6: STK = SimpleTypeKind::Float48;
break;
1579 case 8: STK = SimpleTypeKind::Float64;
break;
1580 case 10: STK = SimpleTypeKind::Float80;
break;
1581 case 16: STK = SimpleTypeKind::Float128;
break;
1584 case dwarf::DW_ATE_signed:
1586 case 1: STK = SimpleTypeKind::SignedCharacter;
break;
1587 case 2: STK = SimpleTypeKind::Int16Short;
break;
1589 case 8: STK = SimpleTypeKind::Int64Quad;
break;
1590 case 16: STK = SimpleTypeKind::Int128Oct;
break;
1593 case dwarf::DW_ATE_unsigned:
1595 case 1: STK = SimpleTypeKind::UnsignedCharacter;
break;
1596 case 2: STK = SimpleTypeKind::UInt16Short;
break;
1598 case 8: STK = SimpleTypeKind::UInt64Quad;
break;
1599 case 16: STK = SimpleTypeKind::UInt128Oct;
break;
1602 case dwarf::DW_ATE_UTF:
1604 case 2: STK = SimpleTypeKind::Character16;
break;
1605 case 4: STK = SimpleTypeKind::Character32;
break;
1608 case dwarf::DW_ATE_signed_char:
1610 STK = SimpleTypeKind::SignedCharacter;
1612 case dwarf::DW_ATE_unsigned_char:
1614 STK = SimpleTypeKind::UnsignedCharacter;
1622 STK = SimpleTypeKind::Int32Long;
1624 STK = SimpleTypeKind::UInt32Long;
1625 if (STK == SimpleTypeKind::UInt16Short &&
1627 STK = SimpleTypeKind::WideCharacter;
1628 if ((STK == SimpleTypeKind::SignedCharacter ||
1629 STK == SimpleTypeKind::UnsignedCharacter) &&
1631 STK = SimpleTypeKind::NarrowCharacter;
1638 TypeIndex PointeeTI = getTypeIndex(Ty->getBaseType());
1644 Ty->
getTag() == dwarf::DW_TAG_pointer_type) {
1646 ? SimpleTypeMode::NearPointer64
1647 : SimpleTypeMode::NearPointer32;
1652 Ty->
getSizeInBits() == 64 ? PointerKind::Near64 : PointerKind::Near32;
1656 case dwarf::DW_TAG_pointer_type:
1657 PM = PointerMode::Pointer;
1659 case dwarf::DW_TAG_reference_type:
1660 PM = PointerMode::LValueReference;
1662 case dwarf::DW_TAG_rvalue_reference_type:
1663 PM = PointerMode::RValueReference;
1668 PO |= PointerOptions::Const;
1671 return TypeTable.writeLeafType(PR);
1683 : PointerToMemberRepresentation::GeneralFunction;
1684 case DINode::FlagSingleInheritance:
1685 return PointerToMemberRepresentation::SingleInheritanceFunction;
1686 case DINode::FlagMultipleInheritance:
1687 return PointerToMemberRepresentation::MultipleInheritanceFunction;
1688 case DINode::FlagVirtualInheritance:
1689 return PointerToMemberRepresentation::VirtualInheritanceFunction;
1695 : PointerToMemberRepresentation::GeneralData;
1696 case DINode::FlagSingleInheritance:
1697 return PointerToMemberRepresentation::SingleInheritanceData;
1698 case DINode::FlagMultipleInheritance:
1699 return PointerToMemberRepresentation::MultipleInheritanceData;
1700 case DINode::FlagVirtualInheritance:
1701 return PointerToMemberRepresentation::VirtualInheritanceData;
1709 assert(Ty->
getTag() == dwarf::DW_TAG_ptr_to_member_type);
1710 TypeIndex ClassTI = getTypeIndex(Ty->getClassType());
1711 TypeIndex PointeeTI = getTypeIndex(Ty->getBaseType(), Ty->getClassType());
1712 PointerKind PK = getPointerSizeInBytes() == 8 ? PointerKind::Near64
1713 : PointerKind::Near32;
1714 bool IsPMF = isa<DISubroutineType>(Ty->getBaseType());
1715 PointerMode PM = IsPMF ? PointerMode::PointerToMemberFunction
1716 : PointerMode::PointerToDataMember;
1723 return TypeTable.writeLeafType(PR);
1730 case dwarf::DW_CC_normal:
return CallingConvention::NearC;
1731 case dwarf::DW_CC_BORLAND_msfastcall:
return CallingConvention::NearFast;
1732 case dwarf::DW_CC_BORLAND_thiscall:
return CallingConvention::ThisCall;
1733 case dwarf::DW_CC_BORLAND_stdcall:
return CallingConvention::NearStdCall;
1734 case dwarf::DW_CC_BORLAND_pascal:
return CallingConvention::NearPascal;
1735 case dwarf::DW_CC_LLVM_vectorcall:
return CallingConvention::NearVector;
1737 return CallingConvention::NearC;
1743 bool IsModifier =
true;
1744 const DIType *BaseTy = Ty;
1745 while (IsModifier && BaseTy) {
1747 switch (BaseTy->
getTag()) {
1748 case dwarf::DW_TAG_const_type:
1749 Mods |= ModifierOptions::Const;
1750 PO |= PointerOptions::Const;
1752 case dwarf::DW_TAG_volatile_type:
1753 Mods |= ModifierOptions::Volatile;
1754 PO |= PointerOptions::Volatile;
1756 case dwarf::DW_TAG_restrict_type:
1759 PO |= PointerOptions::Restrict;
1766 BaseTy = cast<DIDerivedType>(BaseTy)->
getBaseType().resolve();
1774 switch (BaseTy->
getTag()) {
1775 case dwarf::DW_TAG_pointer_type:
1776 case dwarf::DW_TAG_reference_type:
1777 case dwarf::DW_TAG_rvalue_reference_type:
1778 return lowerTypePointer(cast<DIDerivedType>(BaseTy), PO);
1779 case dwarf::DW_TAG_ptr_to_member_type:
1780 return lowerTypeMemberPointer(cast<DIDerivedType>(BaseTy), PO);
1786 TypeIndex ModifiedTI = getTypeIndex(BaseTy);
1794 return TypeTable.writeLeafType(MR);
1800 ReturnAndArgTypeIndices.
push_back(getTypeIndex(ArgTypeRef));
1803 if (ReturnAndArgTypeIndices.
size() > 1 &&
1804 ReturnAndArgTypeIndices.
back() == TypeIndex::Void()) {
1807 TypeIndex ReturnTypeIndex = TypeIndex::Void();
1809 if (!ReturnAndArgTypeIndices.
empty()) {
1810 auto ReturnAndArgTypesRef =
makeArrayRef(ReturnAndArgTypeIndices);
1811 ReturnTypeIndex = ReturnAndArgTypesRef.front();
1812 ArgTypeIndices = ReturnAndArgTypesRef.
drop_front();
1815 ArgListRecord ArgListRec(TypeRecordKind::ArgList, ArgTypeIndices);
1816 TypeIndex ArgListIndex = TypeTable.writeLeafType(ArgListRec);
1823 return TypeTable.writeLeafType(Procedure);
1829 bool IsStaticMethod,
1832 TypeIndex ClassType = getTypeIndex(ClassTy);
1838 TypeIndex ReturnTypeIndex = TypeIndex::Void();
1840 ReturnTypeIndex = getTypeIndex(ReturnAndArgs[Index++]);
1847 if (!IsStaticMethod && ReturnAndArgs.
size() >
Index) {
1849 dyn_cast_or_null<DIDerivedType>(ReturnAndArgs[Index].resolve())) {
1850 if (PtrTy->getTag() == dwarf::DW_TAG_pointer_type) {
1851 ThisTypeIndex = getTypeIndexForThisPtr(PtrTy, Ty);
1857 while (Index < ReturnAndArgs.
size())
1858 ArgTypeIndices.
push_back(getTypeIndex(ReturnAndArgs[Index++]));
1861 if (!ArgTypeIndices.
empty() && ArgTypeIndices.
back() == TypeIndex::Void())
1864 ArgListRecord ArgListRec(TypeRecordKind::ArgList, ArgTypeIndices);
1865 TypeIndex ArgListIndex = TypeTable.writeLeafType(ArgListRec);
1870 ArgTypeIndices.
size(), ArgListIndex, ThisAdjustment);
1871 return TypeTable.writeLeafType(MFR);
1875 unsigned VSlotCount =
1880 return TypeTable.writeLeafType(VFTSR);
1885 case DINode::FlagPrivate:
return MemberAccess::Private;
1886 case DINode::FlagPublic:
return MemberAccess::Public;
1887 case DINode::FlagProtected:
return MemberAccess::Protected;
1890 return RecordTag == dwarf::DW_TAG_class_type ? MemberAccess::Private
1891 : MemberAccess::Public;
1897 if (SP->isArtificial())
1898 return MethodOptions::CompilerGenerated;
1907 if (SP->getFlags() & DINode::FlagStaticMember)
1910 switch (SP->getVirtuality()) {
1911 case dwarf::DW_VIRTUALITY_none:
1913 case dwarf::DW_VIRTUALITY_virtual:
1914 return Introduced ? MethodKind::IntroducingVirtual : MethodKind::Virtual;
1915 case dwarf::DW_VIRTUALITY_pure_virtual:
1916 return Introduced ? MethodKind::PureIntroducingVirtual
1917 : MethodKind::PureVirtual;
1922 return MethodKind::Vanilla;
1928 case dwarf::DW_TAG_structure_type:
return TypeRecordKind::Struct;
1942 CO |= ClassOptions::HasUniqueName;
1948 if (ImmediateScope && isa<DICompositeType>(ImmediateScope))
1949 CO |= ClassOptions::Nested;
1955 if (Ty->
getTag() == dwarf::DW_TAG_enumeration_type) {
1956 if (ImmediateScope && isa<DISubprogram>(ImmediateScope))
1957 CO |= ClassOptions::Scoped;
1959 for (
const DIScope *Scope = ImmediateScope; Scope !=
nullptr;
1961 if (isa<DISubprogram>(Scope)) {
1962 CO |= ClassOptions::Scoped;
1973 case dwarf::DW_TAG_class_type:
1974 case dwarf::DW_TAG_structure_type:
1975 case dwarf::DW_TAG_union_type:
1976 case dwarf::DW_TAG_enumeration_type:
1982 if (
const auto *File = Ty->
getFile()) {
1984 TypeIndex SIDI = TypeTable.writeLeafType(SIDR);
1987 TypeTable.writeLeafType(USLR);
1994 unsigned EnumeratorCount = 0;
1997 CO |= ClassOptions::ForwardReference;
2000 ContinuationBuilder.
begin(ContinuationRecordKind::FieldList);
2004 if (
auto *
Enumerator = dyn_cast_or_null<DIEnumerator>(Element)) {
2012 FTI = TypeTable.insertRecord(ContinuationBuilder);
2019 TypeIndex EnumTI = TypeTable.writeLeafType(ER);
2021 addUDTSrcLine(Ty, EnumTI);
2055 void CodeViewDebug::clear() {
2056 assert(CurFn ==
nullptr);
2058 FnDebugInfo.clear();
2059 FileToFilepathMap.clear();
2062 TypeIndices.clear();
2063 CompleteTypeIndices.clear();
2064 ScopeGlobals.clear();
2070 Info.
Members.push_back({DDTy, 0});
2081 bool FullyResolved =
false;
2082 while (!FullyResolved) {
2084 case dwarf::DW_TAG_const_type:
2085 case dwarf::DW_TAG_volatile_type:
2088 Ty = cast<DIDerivedType>(Ty)->
getBaseType().resolve();
2091 FullyResolved =
true;
2100 ClassInfo NestedInfo = collectClassInfo(DCTy);
2110 for (
auto *Element : Elements) {
2115 if (
auto *SP = dyn_cast<DISubprogram>(Element)) {
2116 Info.
Methods[SP->getRawName()].push_back(SP);
2117 }
else if (
auto *DDTy = dyn_cast<DIDerivedType>(Element)) {
2118 if (DDTy->
getTag() == dwarf::DW_TAG_member) {
2119 collectMemberInfo(Info, DDTy);
2120 }
else if (DDTy->
getTag() == dwarf::DW_TAG_inheritance) {
2122 }
else if (DDTy->
getTag() == dwarf::DW_TAG_pointer_type &&
2123 DDTy->
getName() ==
"__vtbl_ptr_type") {
2124 Info.
VShapeTI = getTypeIndex(DDTy);
2125 }
else if (DDTy->
getTag() == dwarf::DW_TAG_typedef) {
2127 }
else if (DDTy->
getTag() == dwarf::DW_TAG_friend) {
2131 }
else if (
auto *Composite = dyn_cast<DICompositeType>(Element)) {
2155 auto I = CompleteTypeIndices.find(Ty);
2156 if (
I != CompleteTypeIndices.end() &&
I->second ==
TypeIndex())
2158 return getCompleteTypeIndex(Ty);
2169 TypeIndex FwdDeclTI = TypeTable.writeLeafType(CR);
2171 DeferredCompleteTypes.push_back(Ty);
2181 unsigned FieldCount;
2183 std::tie(FieldTI, VShapeTI, FieldCount, ContainsNestedClass) =
2184 lowerRecordFieldList(Ty);
2186 if (ContainsNestedClass)
2187 CO |= ClassOptions::ContainsNestedClass;
2195 TypeIndex ClassTI = TypeTable.writeLeafType(CR);
2197 addUDTSrcLine(Ty, ClassTI);
2207 return getCompleteTypeIndex(Ty);
2213 TypeIndex FwdDeclTI = TypeTable.writeLeafType(UR);
2215 DeferredCompleteTypes.push_back(Ty);
2222 unsigned FieldCount;
2224 std::tie(FieldTI, std::ignore, FieldCount, ContainsNestedClass) =
2225 lowerRecordFieldList(Ty);
2227 if (ContainsNestedClass)
2228 CO |= ClassOptions::ContainsNestedClass;
2233 UnionRecord UR(FieldCount, CO, FieldTI, SizeInBytes, FullName,
2235 TypeIndex UnionTI = TypeTable.writeLeafType(UR);
2237 addUDTSrcLine(Ty, UnionTI);
2244 std::tuple<TypeIndex, TypeIndex, unsigned, bool>
2250 unsigned MemberCount = 0;
2253 ContinuationBuilder.
begin(ContinuationRecordKind::FieldList);
2257 if (I->
getFlags() & DINode::FlagVirtual) {
2259 unsigned VBPtrOffset = I->getVBPtrOffset();
2262 auto RecordKind = (I->
getFlags() & DINode::FlagIndirectVirtualBase) == DINode::FlagIndirectVirtualBase
2263 ? TypeRecordKind::IndirectVirtualBaseClass
2264 : TypeRecordKind::VirtualBaseClass;
2267 getTypeIndex(I->getBaseType()), getVBPTypeIndex(), VBPtrOffset,
2274 "bases must be on byte boundaries");
2276 getTypeIndex(I->getBaseType()),
2286 TypeIndex MemberBaseType = getTypeIndex(Member->getBaseType());
2299 if ((Member->
getFlags() & DINode::FlagArtificial) &&
2301 VFPtrRecord VFPR(getTypeIndex(Member->getBaseType()));
2308 uint64_t MemberOffsetInBits =
2311 uint64_t StartBitOffset = MemberOffsetInBits;
2312 if (
const auto *CI =
2313 dyn_cast_or_null<ConstantInt>(Member->getStorageOffsetInBits())) {
2314 MemberOffsetInBits = CI->getZExtValue() + MemberInfo.
BaseOffset;
2316 StartBitOffset -= MemberOffsetInBits;
2319 MemberBaseType = TypeTable.writeLeafType(BFR);
2321 uint64_t MemberOffsetInBytes = MemberOffsetInBits / 8;
2329 for (
auto &MethodItr : Info.
Methods) {
2332 std::vector<OneMethodRecord> Methods;
2334 TypeIndex MethodType = getMemberFunctionType(SP, Ty);
2335 bool Introduced = SP->getFlags() & DINode::FlagIntroducedVirtual;
2337 unsigned VFTableOffset = -1;
2339 VFTableOffset = SP->getVirtualIndex() * getPointerSizeInBytes();
2347 assert(!Methods.empty() &&
"Empty methods map entry");
2348 if (Methods.size() == 1)
2354 TypeIndex MethodList = TypeTable.writeLeafType(MOLR);
2368 TypeIndex FieldTI = TypeTable.insertRecord(ContinuationBuilder);
2369 return std::make_tuple(FieldTI, Info.
VShapeTI, MemberCount,
2373 TypeIndex CodeViewDebug::getVBPTypeIndex() {
2374 if (!VBPType.getIndex()) {
2377 TypeIndex ModifiedTI = TypeTable.writeLeafType(MR);
2379 PointerKind PK = getPointerSizeInBytes() == 8 ? PointerKind::Near64
2380 : PointerKind::Near32;
2383 PointerRecord PR(ModifiedTI, PK, PM, PO, getPointerSizeInBytes());
2384 VBPType = TypeTable.writeLeafType(PR);
2396 return TypeIndex::Void();
2401 auto I = TypeIndices.find({Ty, ClassTy});
2402 if (
I != TypeIndices.end())
2405 TypeLoweringScope S(*
this);
2407 return recordTypeIndexForDINode(Ty, TI, ClassTy);
2411 CodeViewDebug::getTypeIndexForThisPtr(
const DIDerivedType *PtrTy,
2413 assert(PtrTy->
getTag() == dwarf::DW_TAG_pointer_type &&
2414 "this type must be a pointer type");
2417 if (SubroutineTy->
getFlags() & DINode::DIFlags::FlagLValueReference)
2418 Options = PointerOptions::LValueRefThisPointer;
2419 else if (SubroutineTy->
getFlags() & DINode::DIFlags::FlagRValueReference)
2420 Options = PointerOptions::RValueRefThisPointer;
2427 auto I = TypeIndices.find({PtrTy, SubroutineTy});
2428 if (
I != TypeIndices.end())
2431 TypeLoweringScope S(*
this);
2432 TypeIndex TI = lowerTypePointer(PtrTy, Options);
2433 return recordTypeIndexForDINode(PtrTy, TI, SubroutineTy);
2439 getPointerSizeInBytes() == 8 ? PointerKind::Near64
2440 : PointerKind::Near32,
2443 return TypeTable.writeLeafType(PR);
2451 return TypeIndex::Void();
2456 if (Ty->
getTag() == dwarf::DW_TAG_typedef)
2457 (
void)getTypeIndex(Ty);
2458 while (Ty->
getTag() == dwarf::DW_TAG_typedef)
2459 Ty = cast<DIDerivedType>(Ty)->getBaseType().
resolve();
2464 case dwarf::DW_TAG_class_type:
2465 case dwarf::DW_TAG_structure_type:
2466 case dwarf::DW_TAG_union_type:
2469 return getTypeIndex(Ty);
2473 const auto *CTy = cast<DICompositeType>(Ty);
2474 auto InsertResult = CompleteTypeIndices.insert({CTy,
TypeIndex()});
2475 if (!InsertResult.second)
2476 return InsertResult.first->second;
2478 TypeLoweringScope S(*
this);
2484 if (!CTy->getName().empty() || !CTy->getIdentifier().empty()) {
2485 TypeIndex FwdDeclTI = getTypeIndex(CTy);
2490 if (CTy->isForwardDecl())
2495 switch (CTy->getTag()) {
2496 case dwarf::DW_TAG_class_type:
2497 case dwarf::DW_TAG_structure_type:
2498 TI = lowerCompleteTypeClass(CTy);
2500 case dwarf::DW_TAG_union_type:
2501 TI = lowerCompleteTypeUnion(CTy);
2511 CompleteTypeIndices[CTy] = TI;
2519 void CodeViewDebug::emitDeferredCompleteTypes() {
2521 while (!DeferredCompleteTypes.empty()) {
2522 std::swap(DeferredCompleteTypes, TypesToEmit);
2524 getCompleteTypeIndex(RecordTy);
2525 TypesToEmit.clear();
2529 void CodeViewDebug::emitLocalVariableList(
const FunctionInfo &FI,
2533 for (
const LocalVariable &L : Locals)
2534 if (L.DIVar->isParameter())
2536 llvm::sort(Params, [](
const LocalVariable *L,
const LocalVariable *R) {
2537 return L->DIVar->getArg() < R->DIVar->getArg();
2539 for (
const LocalVariable *L : Params)
2540 emitLocalVariable(FI, *L);
2543 for (
const LocalVariable &L : Locals)
2544 if (!L.DIVar->isParameter())
2545 emitLocalVariable(FI, L);
2550 template <
typename T>
2553 BytePrefix.
resize(2 +
sizeof(
T));
2555 memcpy(&BytePrefix[0], &SymKindLE, 2);
2556 memcpy(&BytePrefix[2], &DefRangeHeader,
sizeof(
T));
2559 void CodeViewDebug::emitLocalVariable(
const FunctionInfo &FI,
2560 const LocalVariable &Var) {
2562 MCSymbol *LocalEnd = beginSymbolRecord(SymbolKind::S_LOCAL);
2565 if (Var.DIVar->isParameter())
2566 Flags |= LocalSymFlags::IsParameter;
2567 if (Var.DefRanges.empty())
2568 Flags |= LocalSymFlags::IsOptimizedOut;
2570 OS.AddComment(
"TypeIndex");
2572 ? getTypeIndexForReferenceTo(Var.DIVar->getType())
2573 : getCompleteTypeIndex(Var.DIVar->getType());
2575 OS.AddComment(
"Flags");
2576 OS.EmitIntValue(static_cast<uint16_t>(Flags), 2);
2579 endSymbolRecord(LocalEnd);
2585 for (
const LocalVarDefRange &DefRange : Var.DefRanges) {
2587 if (DefRange.InMemory) {
2588 int Offset = DefRange.DataOffset;
2589 unsigned Reg = DefRange.CVRegister;
2595 Reg =
unsigned(RegisterId::VFRAME);
2596 Offset += FI.OffsetAdjustment;
2604 (
bool(Flags & LocalSymFlags::IsParameter)
2605 ? (EncFP == FI.EncodedParamFramePtrReg)
2606 : (EncFP == FI.EncodedLocalFramePtrReg))) {
2610 uint16_t RegRelFlags = 0;
2611 if (DefRange.IsSubfield) {
2612 RegRelFlags = DefRangeRegisterRelSym::IsSubfieldFlag |
2613 (DefRange.StructOffset
2614 << DefRangeRegisterRelSym::OffsetInParentShift);
2618 DRHdr.
Flags = RegRelFlags;
2623 assert(DefRange.DataOffset == 0 &&
"unexpected offset into register");
2624 if (DefRange.IsSubfield) {
2626 DRHdr.
Register = DefRange.CVRegister;
2632 DRHdr.
Register = DefRange.CVRegister;
2637 OS.EmitCVDefRangeDirective(DefRange.Ranges, BytePrefix);
2642 const FunctionInfo& FI) {
2643 for (LexicalBlock *Block : Blocks)
2644 emitLexicalBlock(*Block, FI);
2649 void CodeViewDebug::emitLexicalBlock(
const LexicalBlock &Block,
2650 const FunctionInfo& FI) {
2651 MCSymbol *RecordEnd = beginSymbolRecord(SymbolKind::S_BLOCK32);
2652 OS.AddComment(
"PtrParent");
2653 OS.EmitIntValue(0, 4);
2654 OS.AddComment(
"PtrEnd");
2655 OS.EmitIntValue(0, 4);
2656 OS.AddComment(
"Code size");
2657 OS.emitAbsoluteSymbolDiff(Block.End, Block.Begin, 4);
2658 OS.AddComment(
"Function section relative address");
2659 OS.EmitCOFFSecRel32(Block.Begin, 0);
2660 OS.AddComment(
"Function section index");
2661 OS.EmitCOFFSectionIndex(FI.Begin);
2662 OS.AddComment(
"Lexical block name");
2664 endSymbolRecord(RecordEnd);
2667 emitLocalVariableList(FI, Block.Locals);
2668 emitGlobalVariableList(Block.Globals);
2671 emitLexicalBlockList(Block.Children, FI);
2674 emitEndSymbolRecord(SymbolKind::S_END);
2679 void CodeViewDebug::collectLexicalBlockInfo(
2685 collectLexicalBlockInfo(*Scope, Blocks, Locals, Globals);
2690 void CodeViewDebug::collectLexicalBlockInfo(
2700 bool IgnoreScope =
false;
2701 auto LI = ScopeVariables.find(&Scope);
2703 LI != ScopeVariables.
end() ? &LI->second :
nullptr;
2706 GI != ScopeGlobals.
end() ? GI->second.get() :
nullptr;
2711 if (!Locals && !Globals)
2751 auto BlockInsertion = CurFn->LexicalBlocks.insert({DILB, LexicalBlock()});
2752 if (!BlockInsertion.second)
2757 const InsnRange &Range = Ranges.front();
2758 assert(Range.first && Range.second);
2759 LexicalBlock &Block = BlockInsertion.first->second;
2762 assert(Block.Begin &&
"missing label for scope begin");
2763 assert(Block.End &&
"missing label for scope end");
2766 Block.Locals = std::move(*Locals);
2768 Block.Globals = std::move(*Globals);
2778 assert(FnDebugInfo.count(&GV));
2779 assert(CurFn == FnDebugInfo[&GV].
get());
2785 collectLexicalBlockInfo(*CFS,
2793 ScopeVariables.clear();
2797 if (!CurFn->HaveLineInfo && !GV.
getSubprogram()->isThunk()) {
2798 FnDebugInfo.erase(&GV);
2822 for (
const auto &NextMI : *MI->
getParent()) {
2823 if (NextMI.isDebugInstr())
2825 DL = NextMI.getDebugLoc();
2836 maybeRecordLocation(DL,
Asm->
MF);
2842 OS.EmitIntValue(
unsigned(Kind), 4);
2843 OS.AddComment(
"Subsection size");
2844 OS.emitAbsoluteSymbolDiff(EndLabel, BeginLabel, 4);
2845 OS.EmitLabel(BeginLabel);
2849 void CodeViewDebug::endCVSubsection(
MCSymbol *EndLabel) {
2850 OS.EmitLabel(EndLabel);
2852 OS.EmitValueToAlignment(4);
2857 if (EE.Value == SymKind)
2865 OS.AddComment(
"Record length");
2866 OS.emitAbsoluteSymbolDiff(EndLabel, BeginLabel, 2);
2867 OS.EmitLabel(BeginLabel);
2868 if (OS.isVerboseAsm())
2870 OS.EmitIntValue(
unsigned(SymKind), 2);
2874 void CodeViewDebug::endSymbolRecord(
MCSymbol *SymEnd) {
2879 OS.EmitValueToAlignment(4);
2880 OS.EmitLabel(SymEnd);
2883 void CodeViewDebug::emitEndSymbolRecord(
SymbolKind EndKind) {
2884 OS.AddComment(
"Record length");
2885 OS.EmitIntValue(2, 2);
2886 if (OS.isVerboseAsm())
2888 OS.EmitIntValue(
unsigned(EndKind), 2);
2891 void CodeViewDebug::emitDebugInfoForUDTs(
2892 ArrayRef<std::pair<std::string, const DIType *>> UDTs) {
2893 for (
const auto &UDT : UDTs) {
2897 MCSymbol *UDTRecordEnd = beginSymbolRecord(SymbolKind::S_UDT);
2898 OS.AddComment(
"Type");
2899 OS.EmitIntValue(getCompleteTypeIndex(T).getIndex(), 4);
2901 endSymbolRecord(UDTRecordEnd);
2905 void CodeViewDebug::collectGlobalVariableInfo() {
2910 GV.getDebugInfo(GVEs);
2911 for (
const auto *GVE : GVEs)
2912 GlobalMap[GVE] = &GV;
2917 const auto *
CU = cast<DICompileUnit>(Node);
2918 for (
const auto *GVE :
CU->getGlobalVariables()) {
2919 const auto *GV = GlobalMap.
lookup(GVE);
2925 if (Scope && isa<DILocalScope>(Scope)) {
2928 auto Insertion = ScopeGlobals.
insert(
2929 {Scope, std::unique_ptr<GlobalVariableList>()});
2930 if (Insertion.second)
2931 Insertion.first->second = llvm::make_unique<GlobalVariableList>();
2932 VariableList = Insertion.first->second.get();
2935 VariableList = &ComdatVariables;
2938 VariableList = &GlobalVariables;
2939 CVGlobalVariable CVGV = {DIGV, GV};
2945 void CodeViewDebug::emitDebugInfoForGlobals() {
2949 switchToDebugSectionForSymbol(
nullptr);
2950 if (!GlobalVariables.empty()) {
2951 OS.AddComment(
"Symbol subsection for globals");
2952 MCSymbol *EndLabel = beginCVSubsection(DebugSubsectionKind::Symbols);
2953 emitGlobalVariableList(GlobalVariables);
2954 endCVSubsection(EndLabel);
2959 for (
const CVGlobalVariable &CVGV : ComdatVariables) {
2961 OS.AddComment(
"Symbol subsection for " +
2963 switchToDebugSectionForSymbol(GVSym);
2964 MCSymbol *EndLabel = beginCVSubsection(DebugSubsectionKind::Symbols);
2966 emitDebugInfoForGlobal(CVGV.DIGV, CVGV.GV, GVSym);
2967 endCVSubsection(EndLabel);
2971 void CodeViewDebug::emitDebugInfoForRetainedTypes() {
2974 for (
auto *Ty : cast<DICompileUnit>(Node)->getRetainedTypes()) {
2975 if (
DIType *RT = dyn_cast<DIType>(Ty)) {
2985 for (
const CVGlobalVariable &CVGV : Globals) {
2988 emitDebugInfoForGlobal(CVGV.DIGV, CVGV.GV, GVSym);
2999 : SymbolKind::S_GTHREAD32)
3001 : SymbolKind::S_GDATA32);
3002 MCSymbol *DataEnd = beginSymbolRecord(DataSym);
3003 OS.AddComment(
"Type");
3004 OS.EmitIntValue(getCompleteTypeIndex(DIGV->
getType()).getIndex(), 4);
3005 OS.AddComment(
"DataOffset");
3006 OS.EmitCOFFSecRel32(GVSym, 0);
3007 OS.AddComment(
"Segment");
3008 OS.EmitCOFFSectionIndex(GVSym);
3009 OS.AddComment(
"Name");
3010 const unsigned LengthOfDataRecord = 12;
3012 endSymbolRecord(DataEnd);
bool isDeclarationForLinker() const
bool isObjectPointer() const
PointerKind
Equivalent to CV_ptrtype_e.
TypeLoweringScope(CodeViewDebug &CVD)
const TargetLoweringObjectFile & getObjFileLowering() const
Return information about object file lowering.
ArrayRef< std::pair< MCSymbol *, MDNode * > > getCodeViewAnnotations() const
LLVM_NODISCARD StringRef take_front(size_t N=1) const
Return a StringRef equal to 'this' but with only the first N elements remaining.
const DILocalScope * getScopeNode() const
const std::string & getTargetTriple() const
Get the target triple which is a string describing the target host.
uint64_t getOffsetInBits() const
static void copyBytesForDefRange(SmallString< 20 > &BytePrefix, SymbolKind SymKind, const T &DefRangeHeader)
Only call this on endian-specific types like ulittle16_t and little32_t, or structs composed of them...
static bool shouldAlwaysEmitCompleteClassType(const DICompositeType *Ty)
raw_ostream & errs()
This returns a reference to a raw_ostream for standard error.
bool hasLocalLinkage() const
DILocation * get() const
Get the underlying DILocation.
GCNRegPressure max(const GCNRegPressure &P1, const GCNRegPressure &P2)
bool hasDebugInfo() const
Returns true if valid debug info is present.
LLVM_ATTRIBUTE_NORETURN void report_fatal_error(Error Err, bool gen_crash_diag=true)
Report a serious error, calling any installed error handler.
This class represents lattice values for constants.
bool isAbstractScope() const
MCSection * getCOFFDebugTypesSection() const
MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...
bool hasStackProtectorIndex() const
amdgpu Simplify well known AMD library false FunctionCallee Value const Twine & Name
virtual int getFrameIndexReference(const MachineFunction &MF, int FI, unsigned &FrameReg) const
getFrameIndexReference - This method should return the base register and offset used to reference a f...
virtual const TargetRegisterInfo * getRegisterInfo() const
getRegisterInfo - If register information is available, return it.
LLVM_NODISCARD bool startswith(StringRef Prefix) const
Check if this string starts with the given Prefix.
Implements a dense probed hash-table based set.
void push_back(const T &Elt)
const DebugLoc & getDebugLoc() const
Returns the debug location id of this MachineInstr.
SimpleTypeKind getSimpleKind() const
DITypeRef getBaseType() const
virtual void EmitBytes(StringRef Data)
Emit the bytes in Data into the output.
void writeMemberType(RecordType &Record)
void endModule() override
Emit the COFF section that holds the line table information.
TypeIndex writeLeafType(T &Record)
SmallVectorImpl< InsnRange > & getRanges()
static enum BaseType getBaseType(const Value *Val)
Return the baseType for Val which states whether Val is exclusively derived from constant/null, or not exclusively derived from constant.
bool hasFnAttribute(Attribute::AttrKind Kind) const
Return true if the function has the attribute.
A raw_ostream that writes to an SmallVector or SmallString.
auto formatv(const char *Fmt, Ts &&... Vals) -> formatv_object< decltype(std::make_tuple(detail::build_format_adapter(std::forward< Ts >(Vals))...))>
unsigned getPointerSizeInBits(unsigned AS=0) const
Layout pointer size, in bits FIXME: The defaults need to be removed once all of the backends/clients ...
unsigned const TargetRegisterInfo * TRI
MachineFunction * MF
The current machine function.
detail::packed_endian_specific_integral< uint16_t, little, unaligned > ulittle16_t
bool isForwardDecl() const
LexicalScope - This class is used to track scope information.
TinyPtrVector - This class is specialized for cases where there are normally 0 or 1 element in a vect...
void endFunctionImpl(const MachineFunction *) override
Gather post-function debug information.
MCSection * getCOFFGlobalTypeHashesSection() const
StringRef getName() const
VariableDbgInfoMapTy & getVariableDbgInfo()
Tagged DWARF-like metadata node.
std::string fromHex(StringRef Input)
Convert hexadecimal string Input to its binary representation.
DINodeArray getElements() const
SimpleTypeMode getSimpleMode() const
This represents a section on Windows.
MCContext & getContext() const
DebugLoc PrevInstLoc
Previous instruction's location information.
StringRef getName() const
const DataLayout & getDataLayout() const
Get the data layout for the module's target platform.
bool isStaticMember() const
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
SmallVectorImpl< LexicalScope * > & getChildren()
DbgValueHistoryMap DbgValues
History of DBG_VALUE and clobber instructions for each user variable.
ArrayRef< T > makeArrayRef(const T &OneElt)
Construct an ArrayRef from a single element.
LLVM_NODISCARD StringRef drop_front(size_t N=1) const
Return a StringRef equal to 'this' but with the first N elements dropped.
static StringRef getSymbolName(SymbolKind SymKind)
virtual bool hasFP(const MachineFunction &MF) const =0
hasFP - Return true if the specified function should have a dedicated frame pointer register...
static StringRef getName(Value *V)
bool is_absolute(const Twine &path, Style style=Style::native)
Is path absolute?
The MachineFrameInfo class represents an abstract stack frame until prolog/epilog code is inserted...
bool hasVarSizedObjects() const
This method may be called any time after instruction selection is complete to determine if the stack ...
static std::string getFullyQualifiedName(const DIScope *Scope, StringRef Name)
static FunctionOptions getFunctionOptions(const DISubroutineType *Ty, const DICompositeType *ClassTy=nullptr, StringRef SPName=StringRef(""))
uint64_t getSizeInBits() const
void * allocate(unsigned Size, unsigned Align=8)
Holds a subclass of DINode.
LLVM_NODISCARD bool empty() const
empty - Check if the string is empty.
StringRef getFilename() const
static StringRef getPrettyScopeName(const DIScope *Scope)
auto reverse(ContainerTy &&C, typename std::enable_if< has_rbegin< ContainerTy >::value >::type *=nullptr) -> decltype(make_range(C.rbegin(), C.rend()))
bool isLocalToUnit() const
virtual bool EmitCVFileDirective(unsigned FileNo, StringRef Filename, ArrayRef< uint8_t > Checksum, unsigned ChecksumKind)
Associate a filename with a specified logical file number, and also specify that file's checksum info...
static bool canUseReferenceType(const DbgVariableLocation &Loc)
ModifierOptions
Equivalent to CV_modifier_t.
MCSymbol * getFunctionBegin() const
op_range operands() const
static SourceLanguage MapDWLangToCVLang(unsigned DWLang)
static void addLocIfNotPresent(SmallVectorImpl< const DILocation *> &Locs, const DILocation *Loc)
const MCContext & getContext() const
MCSection * getCOFFDebugSymbolsSection() const
NamedMDNode * getNamedMetadata(const Twine &Name) const
Return the first NamedMDNode in the module with the specified name.
LLVM_NODISCARD size_t size() const
size - Get the string size.
LexicalScope * findLexicalScope(const DILocation *DL)
findLexicalScope - Find lexical scope, either regular or inlined, for the given DebugLoc.
bool hasPersonalityFn() const
Check whether this function has a personality function.
MethodKind
Part of member attribute flags. (CV_methodprop_e)
DIScope * getScope() const
iterator_range< op_iterator > operands()
Analysis containing CSE Info
void resolve()
Resolve a unique, unresolved node.
TypeRecordKind
Distinguishes individual records in .debug$T or .debug$P section or PDB type stream.
unsigned getCVBytesOfCalleeSavedRegisters() const
Returns how many bytes of callee-saved registers the target pushed in the prologue.
void beginInstruction(const MachineInstr *MI) override
Process beginning of an instruction.
Streaming machine code generation interface.
EncodedFramePtrReg
Two-bit value indicating which register is the designated frame pointer register. ...
MCSymbol * createTempSymbol(bool CanBeUnnamed=true)
Create and return a new assembler temporary symbol with a unique but unspecified name.
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
CodeGenOpt::Level getOptLevel() const
Returns the optimization level: None, Less, Default, or Aggressive.
static MemberAccess translateAccessFlags(unsigned RecordTag, unsigned Flags)
const MachineBasicBlock * PrevInstBB
const MCAsmInfo * MAI
Target Asm Printer information.
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
The instances of the Type class are immutable: once they are created, they are never changed...
DISubprogram * getSubprogram() const
Get the attached subprogram.
Metadata * getModuleFlag(StringRef Key) const
Return the corresponding value if Key appears in module flags, otherwise return null.
const DILocation * getInlinedAt() const
MachineFrameInfo & getFrameInfo()
getFrameInfo - Return the frame info object for the current function.
StringRef str_data() const
size_t size() const
size - Get the array size.
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
This file contains the declarations for the subclasses of Constant, which represent the different fla...
static CPUType mapArchToCVCPUType(Triple::ArchType Type)
std::vector< MemberInfo > MemberList
AsmPrinter * Asm
Target of debug info emission.
std::pair< iterator, bool > insert(const ValueT &V)
TargetMachine & TM
Target machine description.
This class is intended to be used as a driving class for all asm writers.
EHPersonality classifyEHPersonality(const Value *Pers)
See if the given exception handling personality function is one that we understand.
For method overload sets. LF_METHOD.
bool optForSize() const
Optimize this function for size (-Os) or minimum size (-Oz).
StringRef getCommentString() const
static void replace(Module &M, GlobalVariable *Old, GlobalVariable *New)
constexpr char TypeName[]
Key for Kernel::Arg::Metadata::mTypeName.
void beginInstruction(const MachineInstr *MI) override
Process beginning of an instruction.
Error visitTypeRecord(CVType &Record, TypeIndex Index, TypeVisitorCallbacks &Callbacks, VisitorDataSource Source=VDS_BytesPresent)
void beginFunctionImpl(const MachineFunction *MF) override
Gather pre-function debug information.
StringRef getDirectory() const
MCSymbol * getLabelAfterInsn(const MachineInstr *MI)
Return Label immediately following the instruction.
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
LLVM_NODISCARD char back() const
back - Get the last character in the string.
auto find(R &&Range, const T &Val) -> decltype(adl_begin(Range))
Provide wrappers to std::find which take ranges instead of having to pass begin/end explicitly...
void logAllUnhandledErrors(Error E, raw_ostream &OS, Twine ErrorBanner={})
Log all errors (if any) in E to OS.
bool isDebugInstr() const
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
const DIExpression * getDebugExpression() const
Return the complex address expression referenced by this DBG_VALUE instruction.
Triple - Helper class for working with autoconf configuration names.
static TypeIndex getStringIdTypeIdx(GlobalTypeTableBuilder &TypeTable, StringRef S)
Base class for scope-like contexts.
uint32_t getIndex() const
void sort(IteratorTy Start, IteratorTy End)
PointerOptions
Equivalent to misc lfPointerAttr bitfields.
LexicalScope * findInlinedScope(const DILocalScope *N, const DILocation *IA)
findInlinedScope - Find an inlined scope for the given scope/inlined-at.
Represents the location at which a variable is stored.
SourceLanguage
These values correspond to the CV_CFL_LANG enumeration, and are documented here: https://msdn.microsoft.com/en-us/library/bw3aekw6.aspx.
static Optional< DbgVariableLocation > extractFromMachineInstruction(const MachineInstr &Instruction)
Extract a VariableLocation from a MachineInstr.
This is the shared class of boolean and integer constants.
ArrayRef< EnumEntry< SymbolKind > > getSymbolTypeNames()
void setDebugInfoAvailability(bool avail)
static TypeRecordKind getRecordKind(const DICompositeType *Ty)
StringRef getName() const
MCSymbol * getSymbol(const GlobalValue *GV) const
MCSymbol * getCOMDATSymbol() const
bool isDebugValue() const
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small...
Module.h This file contains the declarations for the Module class.
LLVM_NODISCARD std::pair< StringRef, StringRef > split(char Separator) const
Split into two substrings around the first occurrence of a separator character.
CPUType
These values correspond to the CV_CPU_TYPE_e enumeration, and are documented here: https://msdn...
Information about stack frame layout on the target.
StringRef str()
Return a StringRef for the vector contents.
static GCRegistry::Add< StatepointGC > D("statepoint-example", "an example strategy for statepoint")
DebugLoc getFnDebugLoc() const
Find the debug info location for the start of the function.
MCSymbol * getFunctionEnd() const
const Function & getFunction() const
Return the LLVM function that this machine code represents.
Collects and handles line tables information in a CodeView format.
PointerMode
Equivalent to CV_ptrmode_e.
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
This file contains constants used for implementing Dwarf debug support.
static StringRef dropLLVMManglingEscape(StringRef Name)
If the given string begins with the GlobalValue name mangling escape character '\1', drop it.
bool fragmentsOverlap(const DIExpression *Other) const
Check if fragments overlap between this DIExpression and Other.
MCSection & getSection() const
Get the section associated with a defined, non-absolute symbol.
DebugLoc PrologEndLoc
This location indicates end of function prologue and beginning of function body.
iterator insert(iterator I, T &&Elt)
MethodOptions
Equivalent to CV_fldattr_t bitfield.
void append(in_iter in_start, in_iter in_end)
Add the specified range to the end of the SmallVector.
static const DISubprogram * getQualifiedNameComponents(const DIScope *Scope, SmallVectorImpl< StringRef > &QualifiedNameComponents)
const MachineBasicBlock * getParent() const
Dumper for CodeView type streams found in COFF object files and PDB files.
TargetSubtargetInfo - Generic base class for all target subtargets.
StringRef getIdentifier() const
static MethodKind translateMethodKindFlags(const DISubprogram *SP, bool Introduced)
Type array for a subprogram.
int getCodeViewRegNum(unsigned RegNum) const
Map a target register to an equivalent CodeView register number.
Representation of each machine instruction.
const DIDerivedType * MemberTypeNode
EncodedFramePtrReg encodeFramePtrReg(RegisterId Reg, CPUType CPU)
void setPrefix(StringRef P)
static bool isTrivial(const DICompositeType *DCTy)
unsigned getEncoding() const
void emplace_back(ArgTypes &&... Args)
LLVM_NODISCARD bool empty() const
bool exposesReturnsTwice() const
exposesReturnsTwice - Returns true if the function calls setjmp or any other similar functions with a...
ArrayRef< T > drop_front(size_t N=1) const
Drop the first N elements of the array.
StringRef getName() const
Return a constant reference to the value's name.
static void emitNullTerminatedSymbolName(MCStreamer &OS, StringRef S, unsigned MaxFixedRecordLength=0xF00)
detail::packed_endian_specific_integral< int32_t, little, unaligned > little32_t
bool hasInlineAsm() const
Returns true if the function contains any inline assembly.
virtual const TargetFrameLowering * getFrameLowering() const
bool isZero() const
This is just a convenience method to make client code smaller for a common code.
LLVM_NODISCARD std::enable_if<!is_simple_type< Y >::value, typename cast_retty< X, const Y >::ret_type >::type dyn_cast(const Y &Val)
Base class for debug information backends.
int getOffsetAdjustment() const
Return the correction for frame offsets.
size_type count(const_arg_type_t< ValueT > V) const
Return 1 if the specified key is in the set, 0 otherwise.
static std::string getQualifiedName(ArrayRef< StringRef > QualifiedNameComponents, StringRef TypeName)
SymbolKind
Duplicate copy of the above enum, but using the official CV names.
const Module * getModule() const
ValueT lookup(const_arg_type_t< KeyT > Val) const
lookup - Return the entry for the specified key, or a default constructed value if no such entry exis...
PointerToMemberRepresentation
Equivalent to CV_pmtype_e.
ThunkOrdinal
These values correspond to the THUNK_ORDINAL enumeration.
static Version parseVersion(StringRef Name)
unsigned getCodePointerSize() const
Get the code pointer size in bytes.
DITypeRef getType() const
MCSymbol * getLabelBeforeInsn(const MachineInstr *MI)
Return Label preceding the instruction.
LLVM_NODISCARD const char * data() const
data - Get a pointer to the start of the string (which may not be null terminated).
MemberAccess
Source-level access specifier. (CV_access_e)
SmallVector< int64_t, 1 > LoadChain
Chain of offsetted loads necessary to load the value if it lives in memory.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
static APSInt getUnsigned(uint64_t X)
bool isAsynchronousEHPersonality(EHPersonality Pers)
Returns true if this personality function catches asynchronous exceptions.
static MethodOptions translateMethodOptionFlags(const DISubprogram *SP)
std::vector< const DIType * > NestedTypes
virtual bool EmitCVInlineSiteIdDirective(unsigned FunctionId, unsigned IAFunc, unsigned IAFile, unsigned IALine, unsigned IACol, SMLoc Loc)
Introduces an inline call site id for use with .cv_loc.
bool needsStackRealignment(const MachineFunction &MF) const
True if storage within the function requires the stack pointer to be aligned more than the normal cal...
Constant * getPersonalityFn() const
Get the personality function associated with this function.
DIScopeRef getScope() const
#define LLVM_FALLTHROUGH
LLVM_FALLTHROUGH - Mark fallthrough cases in switch statements.
Lightweight error class with error context and mandatory checking.
static bool shouldEmitUdt(const DIType *T)
CallingConvention
These values correspond to the CV_call_e enumeration, and are documented at the following locations: ...
DITypeRefArray getTypeArray() const
static const unsigned FramePtr
MachineModuleInfo * MMI
Collected machine module information.
bool isThreadLocal() const
If the value is "Thread Local", its value isn't shared by the threads.
iterator_range< global_iterator > globals()
static uint64_t getBaseTypeSize(const DITypeRef TyRef)
If this type is derived from a base type then return base type size.
StringRef - Represent a constant reference to a string, i.e.
static PointerToMemberRepresentation translatePtrToMemberRep(unsigned SizeInBytes, bool IsPMF, unsigned Flags)
static CallingConvention dwarfCCToCodeView(unsigned DwarfCC)
Given a DWARF calling convention, get the CodeView equivalent.
TypedDINodeRef< DIType > DITypeRef
Represents a location in source code.
DILocalScope * getScope() const
Get the local scope for this variable.
unsigned getNumOperands() const
Return number of MDNode operands.
LocalSymFlags
Corresponds to CV_LVARFLAGS bitfield.
uint64_t getStackSize() const
Return the number of bytes that must be allocated to hold all of the fixed size frame objects...
static ClassOptions getCommonClassOptions(const DICompositeType *Ty)
Return ClassOptions that should be present on both the forward declaration and the defintion of a tag...
bool getFlag(MIFlag Flag) const
Return whether an MI flag is set.
void begin(ContinuationRecordKind RecordKind)
CodeViewDebug(AsmPrinter *AP)
MemberList Members
Direct members.
std::pair< const MachineInstr *, const MachineInstr * > InsnRange
InsnRange - This is used to track range of instructions with identical lexical scope.
std::vector< const DIDerivedType * > Inheritance
Base classes.
static bool needsReferenceType(const DbgVariableLocation &Loc)
LexicalScope * getCurrentFunctionScope() const
getCurrentFunctionScope - Return lexical scope for the current function.
Basic type, like 'int' or 'float'.
DIScopeRef getScope() const