42 #include "llvm/Config/llvm-config.h" 98 case Triple::ArchType::x86:
100 case Triple::ArchType::x86_64:
102 case Triple::ArchType::thumb:
104 case Triple::ArchType::aarch64:
127 collectGlobalVariableInfo();
130 ConstantInt *GH = mdconst::extract_or_null<ConstantInt>(
132 EmitDebugGlobalHashes = GH && !GH->
isZero();
136 std::string &Filepath = FileToFilepathMap[
File];
137 if (!Filepath.empty())
144 if (Dir.
startswith(
"/") || Filename.startswith(
"/")) {
148 if (Dir.
back() !=
'/')
150 Filepath += Filename;
158 if (Filename.find(
':') == 1)
161 Filepath = (Dir +
"\\" + Filename).str();
166 std::replace(Filepath.begin(), Filepath.end(),
'/',
'\\');
170 while ((Cursor = Filepath.find(
"\\.\\", Cursor)) != std::string::npos)
171 Filepath.erase(Cursor, 2);
176 while ((Cursor = Filepath.find(
"\\..\\", Cursor)) != std::string::npos) {
181 size_t PrevSlash = Filepath.rfind(
'\\', Cursor - 1);
182 if (PrevSlash == std::string::npos)
186 Filepath.erase(PrevSlash, Cursor + 3 - PrevSlash);
193 while ((Cursor = Filepath.find(
"\\\\", Cursor)) != std::string::npos)
194 Filepath.erase(Cursor, 1);
199 unsigned CodeViewDebug::maybeRecordFile(
const DIFile *
F) {
201 unsigned NextId = FileIdMap.size() + 1;
202 auto Insertion = FileIdMap.insert(std::make_pair(FullPath, NextId));
203 if (Insertion.second) {
207 if (F->getChecksum()) {
208 std::string Checksum =
fromHex(F->getChecksum()->Value);
210 memcpy(CKMem, Checksum.data(), Checksum.size());
212 reinterpret_cast<const uint8_t *
>(CKMem), Checksum.size());
213 switch (F->getChecksum()->Kind) {
219 static_cast<unsigned>(CSKind));
221 assert(Success &&
".cv_file directive failed");
223 return Insertion.first->second;
226 CodeViewDebug::InlineSite &
227 CodeViewDebug::getInlineSite(
const DILocation *InlinedAt,
229 auto SiteInsertion = CurFn->InlineSites.insert({InlinedAt, InlineSite()});
230 InlineSite *Site = &SiteInsertion.first->second;
231 if (SiteInsertion.second) {
232 unsigned ParentFuncId = CurFn->FuncId;
233 if (
const DILocation *OuterIA = InlinedAt->getInlinedAt())
235 getInlineSite(OuterIA, InlinedAt->getScope()->getSubprogram())
238 Site->SiteFuncId = NextFuncId++;
240 Site->SiteFuncId, ParentFuncId, maybeRecordFile(InlinedAt->getFile()),
241 InlinedAt->getLine(), InlinedAt->getColumn(),
SMLoc());
242 Site->Inlinee = Inlinee;
243 InlinedSubprograms.insert(Inlinee);
244 getFuncIdForSubprogram(Inlinee);
251 if (!ScopeName.
empty())
254 switch (Scope->
getTag()) {
255 case dwarf::DW_TAG_enumeration_type:
256 case dwarf::DW_TAG_class_type:
257 case dwarf::DW_TAG_structure_type:
258 case dwarf::DW_TAG_union_type:
259 return "<unnamed-tag>";
260 case dwarf::DW_TAG_namespace:
261 return "`anonymous namespace'";
270 while (Scope !=
nullptr) {
271 if (ClosestSubprogram ==
nullptr)
274 if (!ScopeName.empty())
275 QualifiedNameComponents.
push_back(ScopeName);
278 return ClosestSubprogram;
283 std::string FullyQualifiedName;
286 FullyQualifiedName.append(QualifiedNameComponent);
287 FullyQualifiedName.append(
"::");
289 FullyQualifiedName.append(TypeName);
290 return FullyQualifiedName;
304 if (CVD.TypeEmissionLevel == 1)
305 CVD.emitDeferredCompleteTypes();
306 --CVD.TypeEmissionLevel;
318 if (!Scope || isa<DIFile>(Scope))
321 assert(!isa<DIType>(Scope) &&
"shouldn't make a namespace scope for a type");
324 auto I = TypeIndices.find({Scope,
nullptr});
325 if (
I != TypeIndices.end())
331 auto TI = TypeTable.writeLeafType(SID);
332 return recordTypeIndexForDINode(Scope, TI);
339 auto I = TypeIndices.find({SP,
nullptr});
340 if (
I != TypeIndices.end())
349 if (
const auto *Class = dyn_cast_or_null<DICompositeType>(Scope)) {
353 TypeIndex ClassType = getTypeIndex(Class);
356 TI = TypeTable.writeLeafType(MFuncId);
359 TypeIndex ParentScope = getScopeIndex(Scope);
361 TI = TypeTable.writeLeafType(FuncId);
364 return recordTypeIndexForDINode(SP, TI);
368 return ((DCTy->
getFlags() & DINode::FlagTrivial) == DINode::FlagTrivial);
376 const DIType *ReturnTy =
nullptr;
378 if (TypeArray.size())
379 ReturnTy = TypeArray[0].resolve();
382 if (
auto *ReturnDCTy = dyn_cast_or_null<DICompositeType>(ReturnTy)) {
384 FO |= FunctionOptions::CxxReturnUdt;
388 if (ClassTy && !
isTrivial(ClassTy) && SPName == ClassTy->getName()) {
389 FO |= FunctionOptions::Constructor;
401 if (SP->getDeclaration())
402 SP = SP->getDeclaration();
403 assert(!SP->getDeclaration() &&
"should use declaration as key");
407 auto I = TypeIndices.find({SP, Class});
408 if (I != TypeIndices.end())
414 TypeLoweringScope S(*
this);
415 const bool IsStaticMethod = (SP->getFlags() & DINode::FlagStaticMember) != 0;
419 SP->getType(), Class, SP->getThisAdjustment(), IsStaticMethod, FO);
420 return recordTypeIndexForDINode(SP, TI, Class);
426 auto InsertResult = TypeIndices.insert({{Node, ClassTy}, TI});
428 assert(InsertResult.second &&
"DINode was already assigned a type index");
432 unsigned CodeViewDebug::getPointerSizeInBytes() {
436 void CodeViewDebug::recordLocalVariable(LocalVariable &&Var,
441 InlineSite &Site = getInlineSite(InlinedAt, Inlinee);
442 Site.InlinedLocals.emplace_back(Var);
445 ScopeVariables[
LS].emplace_back(Var);
456 void CodeViewDebug::maybeRecordLocation(
const DebugLoc &DL,
468 if (LI.getStartLine() != DL.
getLine() || LI.isAlwaysStepInto() ||
469 LI.isNeverStepInto())
473 if (CI.getStartColumn() != DL.
getCol())
476 if (!CurFn->HaveLineInfo)
477 CurFn->HaveLineInfo =
true;
480 FileId = CurFn->LastFileId;
482 FileId = CurFn->LastFileId = maybeRecordFile(DL->getFile());
485 unsigned FuncId = CurFn->FuncId;
486 if (
const DILocation *SiteLoc = DL->getInlinedAt()) {
492 getInlineSite(SiteLoc, Loc->getScope()->getSubprogram()).SiteFuncId;
495 bool FirstLoc =
true;
496 while ((SiteLoc = Loc->getInlinedAt())) {
498 getInlineSite(SiteLoc, Loc->getScope()->getSubprogram());
507 OS.EmitCVLocDirective(FuncId, FileId, DL.
getLine(), DL.
getCol(),
509 DL->getFilename(),
SMLoc());
512 void CodeViewDebug::emitCodeViewMagicVersion() {
513 OS.EmitValueToAlignment(4);
514 OS.AddComment(
"Debug section magic");
531 switchToDebugSectionForSymbol(
nullptr);
533 MCSymbol *CompilerInfo = beginCVSubsection(DebugSubsectionKind::Symbols);
534 emitCompilerInformation();
535 endCVSubsection(CompilerInfo);
537 emitInlineeLinesSubsection();
540 for (
auto &
P : FnDebugInfo)
541 if (!
P.first->isDeclarationForLinker())
542 emitDebugInfoForFunction(
P.first, *
P.second);
545 setCurrentSubprogram(
nullptr);
546 emitDebugInfoForGlobals();
549 emitDebugInfoForRetainedTypes();
553 switchToDebugSectionForSymbol(
nullptr);
556 if (!GlobalUDTs.empty()) {
557 MCSymbol *SymbolsEnd = beginCVSubsection(DebugSubsectionKind::Symbols);
558 emitDebugInfoForUDTs(GlobalUDTs);
559 endCVSubsection(SymbolsEnd);
563 OS.AddComment(
"File index to string table offset subsection");
564 OS.EmitCVFileChecksumsDirective();
567 OS.AddComment(
"String table");
568 OS.EmitCVStringTableDirective();
577 emitTypeInformation();
579 if (EmitDebugGlobalHashes)
580 emitTypeGlobalHashes();
586 unsigned MaxFixedRecordLength = 0xF00) {
597 void CodeViewDebug::emitTypeInformation() {
598 if (TypeTable.empty())
603 emitCodeViewMagicVersion();
606 if (OS.isVerboseAsm()) {
607 CommentPrefix +=
'\t';
609 CommentPrefix +=
' ';
618 if (OS.isVerboseAsm()) {
637 OS.EmitBinaryData(Record.
str_data());
638 B = Table.getNext(*B);
642 void CodeViewDebug::emitTypeGlobalHashes() {
643 if (TypeTable.empty())
650 OS.EmitValueToAlignment(4);
651 OS.AddComment(
"Magic");
653 OS.AddComment(
"Section Version");
654 OS.EmitIntValue(0, 2);
655 OS.AddComment(
"Hash Algorithm");
656 OS.EmitIntValue(uint16_t(GlobalTypeHashAlg::SHA1_8), 2);
658 TypeIndex TI(TypeIndex::FirstNonSimpleIndex);
659 for (
const auto &GHR : TypeTable.hashes()) {
660 if (OS.isVerboseAsm()) {
666 OS.AddComment(Comment);
669 assert(GHR.Hash.size() == 8);
670 StringRef S(reinterpret_cast<const char *>(GHR.Hash.data()),
672 OS.EmitBinaryData(S);
678 case dwarf::DW_LANG_C:
679 case dwarf::DW_LANG_C89:
680 case dwarf::DW_LANG_C99:
681 case dwarf::DW_LANG_C11:
682 case dwarf::DW_LANG_ObjC:
684 case dwarf::DW_LANG_C_plus_plus:
685 case dwarf::DW_LANG_C_plus_plus_03:
686 case dwarf::DW_LANG_C_plus_plus_11:
687 case dwarf::DW_LANG_C_plus_plus_14:
689 case dwarf::DW_LANG_Fortran77:
690 case dwarf::DW_LANG_Fortran90:
691 case dwarf::DW_LANG_Fortran03:
692 case dwarf::DW_LANG_Fortran08:
694 case dwarf::DW_LANG_Pascal83:
696 case dwarf::DW_LANG_Cobol74:
697 case dwarf::DW_LANG_Cobol85:
699 case dwarf::DW_LANG_Java:
701 case dwarf::DW_LANG_D:
722 for (
const char C : Name) {
725 V.Part[
N] +=
C -
'0';
726 }
else if (
C ==
'.') {
736 void CodeViewDebug::emitCompilerInformation() {
737 MCSymbol *CompilerEnd = beginSymbolRecord(SymbolKind::S_COMPILE3);
742 const auto *
CU = cast<DICompileUnit>(Node);
748 OS.AddComment(
"Flags and language");
749 OS.EmitIntValue(Flags, 4);
751 OS.AddComment(
"CPUType");
752 OS.EmitIntValue(static_cast<uint64_t>(TheCPU), 2);
756 OS.AddComment(
"Frontend version");
757 for (
int N = 0;
N < 4; ++
N)
758 OS.EmitIntValue(FrontVer.Part[
N], 2);
763 int Major = 1000 * LLVM_VERSION_MAJOR +
764 10 * LLVM_VERSION_MINOR +
768 Version BackVer = {{ Major, 0, 0, 0 }};
769 OS.AddComment(
"Backend version");
770 for (
int N = 0;
N < 4; ++
N)
771 OS.EmitIntValue(BackVer.Part[
N], 2);
773 OS.AddComment(
"Null-terminated compiler version string");
776 endSymbolRecord(CompilerEnd);
785 void CodeViewDebug::emitBuildInfo() {
796 TypeIndex BuildInfoArgs[BuildInfoRecord::MaxArgs] = {};
799 const auto *
CU = cast<DICompileUnit>(Node);
800 const DIFile *MainSourceFile =
CU->getFile();
801 BuildInfoArgs[BuildInfoRecord::CurrentDirectory] =
803 BuildInfoArgs[BuildInfoRecord::SourceFile] =
808 TypeIndex BuildInfoIndex = TypeTable.writeLeafType(BIR);
812 MCSymbol *BISubsecEnd = beginCVSubsection(DebugSubsectionKind::Symbols);
813 MCSymbol *BIEnd = beginSymbolRecord(SymbolKind::S_BUILDINFO);
814 OS.AddComment(
"LF_BUILDINFO index");
815 OS.EmitIntValue(BuildInfoIndex.
getIndex(), 4);
816 endSymbolRecord(BIEnd);
817 endCVSubsection(BISubsecEnd);
820 void CodeViewDebug::emitInlineeLinesSubsection() {
821 if (InlinedSubprograms.empty())
824 OS.AddComment(
"Inlinee lines subsection");
825 MCSymbol *InlineEnd = beginCVSubsection(DebugSubsectionKind::InlineeLines);
831 OS.AddComment(
"Inlinee lines signature");
832 OS.EmitIntValue(
unsigned(InlineeLinesSignature::Normal), 4);
835 assert(TypeIndices.count({SP, nullptr}));
836 TypeIndex InlineeIdx = TypeIndices[{SP,
nullptr}];
839 unsigned FileId = maybeRecordFile(SP->
getFile());
840 OS.AddComment(
"Inlined function " + SP->
getName() +
" starts at " +
843 OS.AddComment(
"Type index of inlined function");
844 OS.EmitIntValue(InlineeIdx.getIndex(), 4);
845 OS.AddComment(
"Offset into filechecksum table");
846 OS.EmitCVFileChecksumOffsetDirective(FileId);
847 OS.AddComment(
"Starting line number");
848 OS.EmitIntValue(SP->getLine(), 4);
851 endCVSubsection(InlineEnd);
854 void CodeViewDebug::emitInlinedCallSite(
const FunctionInfo &FI,
856 const InlineSite &Site) {
857 assert(TypeIndices.count({Site.Inlinee, nullptr}));
858 TypeIndex InlineeIdx = TypeIndices[{Site.Inlinee,
nullptr}];
861 MCSymbol *InlineEnd = beginSymbolRecord(SymbolKind::S_INLINESITE);
863 OS.AddComment(
"PtrParent");
864 OS.EmitIntValue(0, 4);
865 OS.AddComment(
"PtrEnd");
866 OS.EmitIntValue(0, 4);
867 OS.AddComment(
"Inlinee type index");
868 OS.EmitIntValue(InlineeIdx.getIndex(), 4);
870 unsigned FileId = maybeRecordFile(Site.Inlinee->getFile());
871 unsigned StartLineNum = Site.Inlinee->getLine();
873 OS.EmitCVInlineLinetableDirective(Site.SiteFuncId, FileId, StartLineNum,
876 endSymbolRecord(InlineEnd);
878 emitLocalVariableList(FI, Site.InlinedLocals);
881 for (
const DILocation *ChildSite : Site.ChildSites) {
882 auto I = FI.InlineSites.find(ChildSite);
883 assert(
I != FI.InlineSites.end() &&
884 "child site not in function inline site map");
885 emitInlinedCallSite(FI, ChildSite,
I->second);
889 emitEndSymbolRecord(SymbolKind::S_INLINESITE_END);
892 void CodeViewDebug::switchToDebugSectionForSymbol(
const MCSymbol *GVSym) {
902 DebugSec = OS.getContext().getAssociativeCOFFSection(DebugSec, KeySym);
904 OS.SwitchSection(DebugSec);
908 if (ComdatDebugSections.insert(DebugSec).second)
909 emitCodeViewMagicVersion();
914 void CodeViewDebug::emitDebugInfoForThunk(
const Function *GV,
920 OS.AddComment(
"Symbol subsection for " +
Twine(FuncName));
921 MCSymbol *SymbolsEnd = beginCVSubsection(DebugSubsectionKind::Symbols);
924 MCSymbol *ThunkRecordEnd = beginSymbolRecord(SymbolKind::S_THUNK32);
925 OS.AddComment(
"PtrParent");
926 OS.EmitIntValue(0, 4);
927 OS.AddComment(
"PtrEnd");
928 OS.EmitIntValue(0, 4);
929 OS.AddComment(
"PtrNext");
930 OS.EmitIntValue(0, 4);
931 OS.AddComment(
"Thunk section relative address");
932 OS.EmitCOFFSecRel32(Fn, 0);
933 OS.AddComment(
"Thunk section index");
934 OS.EmitCOFFSectionIndex(Fn);
935 OS.AddComment(
"Code size");
936 OS.emitAbsoluteSymbolDiff(FI.End, Fn, 2);
937 OS.AddComment(
"Ordinal");
938 OS.EmitIntValue(
unsigned(ordinal), 1);
939 OS.AddComment(
"Function name");
942 endSymbolRecord(ThunkRecordEnd);
948 emitEndSymbolRecord(SymbolKind::S_PROC_ID_END);
950 endCVSubsection(SymbolsEnd);
953 void CodeViewDebug::emitDebugInfoForFunction(
const Function *GV,
961 switchToDebugSectionForSymbol(Fn);
963 std::string FuncName;
966 setCurrentSubprogram(SP);
969 emitDebugInfoForThunk(GV, FI, Fn);
980 if (FuncName.empty())
985 OS.EmitCVFPOData(Fn);
988 OS.AddComment(
"Symbol subsection for " +
Twine(FuncName));
989 MCSymbol *SymbolsEnd = beginCVSubsection(DebugSubsectionKind::Symbols);
992 : SymbolKind::S_GPROC32_ID;
993 MCSymbol *ProcRecordEnd = beginSymbolRecord(ProcKind);
996 OS.AddComment(
"PtrParent");
997 OS.EmitIntValue(0, 4);
998 OS.AddComment(
"PtrEnd");
999 OS.EmitIntValue(0, 4);
1000 OS.AddComment(
"PtrNext");
1001 OS.EmitIntValue(0, 4);
1004 OS.AddComment(
"Code size");
1005 OS.emitAbsoluteSymbolDiff(FI.End, Fn, 4);
1006 OS.AddComment(
"Offset after prologue");
1007 OS.EmitIntValue(0, 4);
1008 OS.AddComment(
"Offset before epilogue");
1009 OS.EmitIntValue(0, 4);
1010 OS.AddComment(
"Function type index");
1011 OS.EmitIntValue(getFuncIdForSubprogram(GV->
getSubprogram()).getIndex(), 4);
1012 OS.AddComment(
"Function section relative address");
1013 OS.EmitCOFFSecRel32(Fn, 0);
1014 OS.AddComment(
"Function section index");
1015 OS.EmitCOFFSectionIndex(Fn);
1016 OS.AddComment(
"Flags");
1017 OS.EmitIntValue(0, 1);
1019 OS.AddComment(
"Function name");
1022 endSymbolRecord(ProcRecordEnd);
1024 MCSymbol *FrameProcEnd = beginSymbolRecord(SymbolKind::S_FRAMEPROC);
1026 OS.AddComment(
"FrameSize");
1027 OS.EmitIntValue(FI.FrameSize - FI.CSRSize, 4);
1028 OS.AddComment(
"Padding");
1029 OS.EmitIntValue(0, 4);
1030 OS.AddComment(
"Offset of padding");
1031 OS.EmitIntValue(0, 4);
1032 OS.AddComment(
"Bytes of callee saved registers");
1033 OS.EmitIntValue(FI.CSRSize, 4);
1034 OS.AddComment(
"Exception handler offset");
1035 OS.EmitIntValue(0, 4);
1036 OS.AddComment(
"Exception handler section");
1037 OS.EmitIntValue(0, 2);
1038 OS.AddComment(
"Flags (defines frame register)");
1039 OS.EmitIntValue(
uint32_t(FI.FrameProcOpts), 4);
1040 endSymbolRecord(FrameProcEnd);
1042 emitLocalVariableList(FI, FI.Locals);
1043 emitGlobalVariableList(FI.Globals);
1044 emitLexicalBlockList(FI.ChildBlocks, FI);
1049 for (
const DILocation *InlinedAt : FI.ChildSites) {
1050 auto I = FI.InlineSites.find(InlinedAt);
1051 assert(
I != FI.InlineSites.end() &&
1052 "child site not in function inline site map");
1053 emitInlinedCallSite(FI, InlinedAt,
I->second);
1056 for (
auto Annot : FI.Annotations) {
1058 MDTuple *Strs = cast<MDTuple>(Annot.second);
1059 MCSymbol *AnnotEnd = beginSymbolRecord(SymbolKind::S_ANNOTATION);
1060 OS.EmitCOFFSecRel32(Label, 0);
1062 OS.EmitCOFFSectionIndex(Label);
1067 StringRef Str = cast<MDString>(MD)->getString();
1068 assert(Str.
data()[Str.
size()] ==
'\0' &&
"non-nullterminated MDString");
1071 endSymbolRecord(AnnotEnd);
1075 emitDebugInfoForUDTs(LocalUDTs);
1078 emitEndSymbolRecord(SymbolKind::S_PROC_ID_END);
1080 endCVSubsection(SymbolsEnd);
1083 OS.EmitCVLinetableDirective(FI.FuncId, Fn, FI.End);
1086 CodeViewDebug::LocalVarDefRange
1087 CodeViewDebug::createDefRangeMem(uint16_t CVRegister,
int Offset) {
1088 LocalVarDefRange DR;
1091 assert(DR.DataOffset == Offset &&
"truncation");
1093 DR.StructOffset = 0;
1094 DR.CVRegister = CVRegister;
1098 void CodeViewDebug::collectVariableInfoFromMFTable(
1108 assert(
VI.Var->isValidLocationForIntrinsic(
VI.Loc) &&
1109 "Expected inlined-at fields to agree");
1111 Processed.
insert(InlinedEntity(
VI.Var,
VI.Loc->getInlinedAt()));
1120 int64_t ExprOffset = 0;
1122 if (!
VI.Expr->extractIfOffset(ExprOffset))
1126 unsigned FrameReg = 0;
1131 LocalVarDefRange DefRange =
1132 createDefRangeMem(CVReg, FrameOffset + ExprOffset);
1137 DefRange.Ranges.emplace_back(Begin, End);
1142 Var.DefRanges.emplace_back(std::move(DefRange));
1143 recordLocalVariable(std::move(Var), Scope);
1155 void CodeViewDebug::calculateRanges(
1160 for (
auto I = Ranges.
begin(),
E = Ranges.
end();
I !=
E; ++
I) {
1178 if (Var.UseReferenceType) {
1181 Location->LoadChain.pop_back();
1187 Var.UseReferenceType =
true;
1188 Var.DefRanges.clear();
1189 calculateRanges(Var, Ranges);
1194 if (Location->Register == 0 || Location->LoadChain.size() > 1)
1197 LocalVarDefRange DR;
1199 DR.InMemory = !Location->LoadChain.empty();
1201 !Location->LoadChain.empty() ? Location->LoadChain.back() : 0;
1202 if (Location->FragmentInfo) {
1203 DR.IsSubfield =
true;
1204 DR.StructOffset = Location->FragmentInfo->OffsetInBits / 8;
1206 DR.IsSubfield =
false;
1207 DR.StructOffset = 0;
1210 if (Var.DefRanges.empty() ||
1211 Var.DefRanges.back().isDifferentLocation(DR)) {
1212 Var.DefRanges.emplace_back(std::move(DR));
1222 auto J = std::next(
I);
1236 Var.DefRanges.back().Ranges;
1237 if (!R.
empty() && R.
back().second == Begin)
1238 R.
back().second = End;
1246 void CodeViewDebug::collectVariableInfo(
const DISubprogram *SP) {
1249 collectVariableInfoFromMFTable(Processed);
1252 InlinedEntity IV =
I.first;
1253 if (Processed.
count(IV))
1259 const auto &Ranges =
I.second;
1273 calculateRanges(Var, Ranges);
1274 recordLocalVariable(std::move(Var), Scope);
1283 auto Insertion = FnDebugInfo.insert({&GV, llvm::make_unique<FunctionInfo>()});
1284 assert(Insertion.second &&
"function already has info");
1285 CurFn = Insertion.first->second.get();
1286 CurFn->FuncId = NextFuncId++;
1301 if (CurFn->FrameSize > 0) {
1303 CurFn->EncodedLocalFramePtrReg = EncodedFramePtrReg::StackPtr;
1304 CurFn->EncodedParamFramePtrReg = EncodedFramePtrReg::StackPtr;
1308 if (CurFn->HasStackRealignment) {
1310 CurFn->EncodedLocalFramePtrReg = EncodedFramePtrReg::StackPtr;
1322 FPO |= FrameProcedureOptions::HasAlloca;
1324 FPO |= FrameProcedureOptions::HasSetJmp;
1327 FPO |= FrameProcedureOptions::HasInlineAssembly;
1331 FPO |= FrameProcedureOptions::HasStructuredExceptionHandling;
1333 FPO |= FrameProcedureOptions::HasExceptionHandling;
1336 FPO |= FrameProcedureOptions::MarkedInline;
1338 FPO |= FrameProcedureOptions::Naked;
1340 FPO |= FrameProcedureOptions::SecurityChecks;
1345 FPO |= FrameProcedureOptions::OptimizedForSpeed;
1347 CurFn->FrameProcOpts = FPO;
1349 OS.EmitCVFuncIdDirective(CurFn->FuncId);
1356 bool EmptyPrologue =
true;
1357 for (
const auto &MBB : *MF) {
1358 for (
const auto &
MI : MBB) {
1361 PrologEndLoc =
MI.getDebugLoc();
1363 }
else if (!
MI.isMetaInstruction()) {
1364 EmptyPrologue =
false;
1370 if (PrologEndLoc && !EmptyPrologue) {
1372 maybeRecordLocation(FnStartDL, MF);
1381 if (T->
getTag() == dwarf::DW_TAG_typedef) {
1383 switch (Scope->
getTag()) {
1384 case dwarf::DW_TAG_structure_type:
1385 case dwarf::DW_TAG_class_type:
1386 case dwarf::DW_TAG_union_type:
1399 T = DT->getBaseType().
resolve();
1404 void CodeViewDebug::addToUDTs(
const DIType *Ty) {
1415 std::string FullyQualifiedName =
1418 if (ClosestSubprogram ==
nullptr) {
1419 GlobalUDTs.emplace_back(std::move(FullyQualifiedName), Ty);
1420 }
else if (ClosestSubprogram == CurrentSubprogram) {
1421 LocalUDTs.emplace_back(std::move(FullyQualifiedName), Ty);
1435 case dwarf::DW_TAG_array_type:
1436 return lowerTypeArray(cast<DICompositeType>(Ty));
1437 case dwarf::DW_TAG_typedef:
1438 return lowerTypeAlias(cast<DIDerivedType>(Ty));
1439 case dwarf::DW_TAG_base_type:
1440 return lowerTypeBasic(cast<DIBasicType>(Ty));
1441 case dwarf::DW_TAG_pointer_type:
1442 if (cast<DIDerivedType>(Ty)->
getName() ==
"__vtbl_ptr_type")
1443 return lowerTypeVFTableShape(cast<DIDerivedType>(Ty));
1445 case dwarf::DW_TAG_reference_type:
1446 case dwarf::DW_TAG_rvalue_reference_type:
1447 return lowerTypePointer(cast<DIDerivedType>(Ty));
1448 case dwarf::DW_TAG_ptr_to_member_type:
1449 return lowerTypeMemberPointer(cast<DIDerivedType>(Ty));
1450 case dwarf::DW_TAG_restrict_type:
1451 case dwarf::DW_TAG_const_type:
1452 case dwarf::DW_TAG_volatile_type:
1454 return lowerTypeModifier(cast<DIDerivedType>(Ty));
1455 case dwarf::DW_TAG_subroutine_type:
1459 return lowerTypeMemberFunction(cast<DISubroutineType>(Ty), ClassTy,
1463 return lowerTypeFunction(cast<DISubroutineType>(Ty));
1464 case dwarf::DW_TAG_enumeration_type:
1465 return lowerTypeEnum(cast<DICompositeType>(Ty));
1466 case dwarf::DW_TAG_class_type:
1467 case dwarf::DW_TAG_structure_type:
1468 return lowerTypeClass(cast<DICompositeType>(Ty));
1469 case dwarf::DW_TAG_union_type:
1470 return lowerTypeUnion(cast<DICompositeType>(Ty));
1471 case dwarf::DW_TAG_unspecified_type:
1472 if (Ty->
getName() ==
"decltype(nullptr)")
1473 return TypeIndex::NullptrT();
1482 DITypeRef UnderlyingTypeRef = Ty->getBaseType();
1483 TypeIndex UnderlyingTypeIndex = getTypeIndex(UnderlyingTypeRef);
1488 if (UnderlyingTypeIndex ==
TypeIndex(SimpleTypeKind::Int32Long) &&
1489 TypeName ==
"HRESULT")
1490 return TypeIndex(SimpleTypeKind::HResult);
1491 if (UnderlyingTypeIndex ==
TypeIndex(SimpleTypeKind::UInt16Short) &&
1492 TypeName ==
"wchar_t")
1493 return TypeIndex(SimpleTypeKind::WideCharacter);
1495 return UnderlyingTypeIndex;
1500 TypeIndex ElementTypeIndex = getTypeIndex(ElementTypeRef);
1502 TypeIndex IndexType = getPointerSizeInBytes() == 8
1504 :
TypeIndex(SimpleTypeKind::UInt32Long);
1510 for (
int i = Elements.size() - 1; i >= 0; --i) {
1511 const DINode *Element = Elements[i];
1512 assert(Element->
getTag() == dwarf::DW_TAG_subrange_type);
1514 const DISubrange *Subrange = cast<DISubrange>(Element);
1515 assert(Subrange->getLowerBound() == 0 &&
1516 "codeview doesn't support subranges with lower bounds");
1518 if (
auto *CI = Subrange->getCount().dyn_cast<
ConstantInt*>())
1519 Count = CI->getSExtValue();
1529 ElementSize *= Count;
1533 uint64_t ArraySize =
1534 (i == 0 && ElementSize == 0) ? Ty->
getSizeInBits() / 8 : ElementSize;
1537 ArrayRecord AR(ElementTypeIndex, IndexType, ArraySize, Name);
1538 ElementTypeIndex = TypeTable.writeLeafType(AR);
1541 return ElementTypeIndex;
1554 case dwarf::DW_ATE_address:
1557 case dwarf::DW_ATE_boolean:
1559 case 1: STK = SimpleTypeKind::Boolean8;
break;
1560 case 2: STK = SimpleTypeKind::Boolean16;
break;
1561 case 4: STK = SimpleTypeKind::Boolean32;
break;
1562 case 8: STK = SimpleTypeKind::Boolean64;
break;
1563 case 16: STK = SimpleTypeKind::Boolean128;
break;
1566 case dwarf::DW_ATE_complex_float:
1568 case 2: STK = SimpleTypeKind::Complex16;
break;
1569 case 4: STK = SimpleTypeKind::Complex32;
break;
1570 case 8: STK = SimpleTypeKind::Complex64;
break;
1571 case 10: STK = SimpleTypeKind::Complex80;
break;
1572 case 16: STK = SimpleTypeKind::Complex128;
break;
1575 case dwarf::DW_ATE_float:
1577 case 2: STK = SimpleTypeKind::Float16;
break;
1578 case 4: STK = SimpleTypeKind::Float32;
break;
1579 case 6: STK = SimpleTypeKind::Float48;
break;
1580 case 8: STK = SimpleTypeKind::Float64;
break;
1581 case 10: STK = SimpleTypeKind::Float80;
break;
1582 case 16: STK = SimpleTypeKind::Float128;
break;
1585 case dwarf::DW_ATE_signed:
1587 case 1: STK = SimpleTypeKind::SignedCharacter;
break;
1588 case 2: STK = SimpleTypeKind::Int16Short;
break;
1590 case 8: STK = SimpleTypeKind::Int64Quad;
break;
1591 case 16: STK = SimpleTypeKind::Int128Oct;
break;
1594 case dwarf::DW_ATE_unsigned:
1596 case 1: STK = SimpleTypeKind::UnsignedCharacter;
break;
1597 case 2: STK = SimpleTypeKind::UInt16Short;
break;
1599 case 8: STK = SimpleTypeKind::UInt64Quad;
break;
1600 case 16: STK = SimpleTypeKind::UInt128Oct;
break;
1603 case dwarf::DW_ATE_UTF:
1605 case 2: STK = SimpleTypeKind::Character16;
break;
1606 case 4: STK = SimpleTypeKind::Character32;
break;
1609 case dwarf::DW_ATE_signed_char:
1611 STK = SimpleTypeKind::SignedCharacter;
1613 case dwarf::DW_ATE_unsigned_char:
1615 STK = SimpleTypeKind::UnsignedCharacter;
1623 STK = SimpleTypeKind::Int32Long;
1625 STK = SimpleTypeKind::UInt32Long;
1626 if (STK == SimpleTypeKind::UInt16Short &&
1628 STK = SimpleTypeKind::WideCharacter;
1629 if ((STK == SimpleTypeKind::SignedCharacter ||
1630 STK == SimpleTypeKind::UnsignedCharacter) &&
1632 STK = SimpleTypeKind::NarrowCharacter;
1639 TypeIndex PointeeTI = getTypeIndex(Ty->getBaseType());
1645 Ty->
getTag() == dwarf::DW_TAG_pointer_type) {
1647 ? SimpleTypeMode::NearPointer64
1648 : SimpleTypeMode::NearPointer32;
1653 Ty->
getSizeInBits() == 64 ? PointerKind::Near64 : PointerKind::Near32;
1657 case dwarf::DW_TAG_pointer_type:
1658 PM = PointerMode::Pointer;
1660 case dwarf::DW_TAG_reference_type:
1661 PM = PointerMode::LValueReference;
1663 case dwarf::DW_TAG_rvalue_reference_type:
1664 PM = PointerMode::RValueReference;
1669 PO |= PointerOptions::Const;
1672 return TypeTable.writeLeafType(PR);
1684 : PointerToMemberRepresentation::GeneralFunction;
1685 case DINode::FlagSingleInheritance:
1686 return PointerToMemberRepresentation::SingleInheritanceFunction;
1687 case DINode::FlagMultipleInheritance:
1688 return PointerToMemberRepresentation::MultipleInheritanceFunction;
1689 case DINode::FlagVirtualInheritance:
1690 return PointerToMemberRepresentation::VirtualInheritanceFunction;
1696 : PointerToMemberRepresentation::GeneralData;
1697 case DINode::FlagSingleInheritance:
1698 return PointerToMemberRepresentation::SingleInheritanceData;
1699 case DINode::FlagMultipleInheritance:
1700 return PointerToMemberRepresentation::MultipleInheritanceData;
1701 case DINode::FlagVirtualInheritance:
1702 return PointerToMemberRepresentation::VirtualInheritanceData;
1710 assert(Ty->
getTag() == dwarf::DW_TAG_ptr_to_member_type);
1711 TypeIndex ClassTI = getTypeIndex(Ty->getClassType());
1712 TypeIndex PointeeTI = getTypeIndex(Ty->getBaseType(), Ty->getClassType());
1713 PointerKind PK = getPointerSizeInBytes() == 8 ? PointerKind::Near64
1714 : PointerKind::Near32;
1715 bool IsPMF = isa<DISubroutineType>(Ty->getBaseType());
1716 PointerMode PM = IsPMF ? PointerMode::PointerToMemberFunction
1717 : PointerMode::PointerToDataMember;
1724 return TypeTable.writeLeafType(PR);
1731 case dwarf::DW_CC_normal:
return CallingConvention::NearC;
1732 case dwarf::DW_CC_BORLAND_msfastcall:
return CallingConvention::NearFast;
1733 case dwarf::DW_CC_BORLAND_thiscall:
return CallingConvention::ThisCall;
1734 case dwarf::DW_CC_BORLAND_stdcall:
return CallingConvention::NearStdCall;
1735 case dwarf::DW_CC_BORLAND_pascal:
return CallingConvention::NearPascal;
1736 case dwarf::DW_CC_LLVM_vectorcall:
return CallingConvention::NearVector;
1738 return CallingConvention::NearC;
1744 bool IsModifier =
true;
1745 const DIType *BaseTy = Ty;
1746 while (IsModifier && BaseTy) {
1748 switch (BaseTy->
getTag()) {
1749 case dwarf::DW_TAG_const_type:
1750 Mods |= ModifierOptions::Const;
1751 PO |= PointerOptions::Const;
1753 case dwarf::DW_TAG_volatile_type:
1754 Mods |= ModifierOptions::Volatile;
1755 PO |= PointerOptions::Volatile;
1757 case dwarf::DW_TAG_restrict_type:
1760 PO |= PointerOptions::Restrict;
1767 BaseTy = cast<DIDerivedType>(BaseTy)->
getBaseType().resolve();
1775 switch (BaseTy->
getTag()) {
1776 case dwarf::DW_TAG_pointer_type:
1777 case dwarf::DW_TAG_reference_type:
1778 case dwarf::DW_TAG_rvalue_reference_type:
1779 return lowerTypePointer(cast<DIDerivedType>(BaseTy), PO);
1780 case dwarf::DW_TAG_ptr_to_member_type:
1781 return lowerTypeMemberPointer(cast<DIDerivedType>(BaseTy), PO);
1787 TypeIndex ModifiedTI = getTypeIndex(BaseTy);
1795 return TypeTable.writeLeafType(MR);
1801 ReturnAndArgTypeIndices.
push_back(getTypeIndex(ArgTypeRef));
1804 if (ReturnAndArgTypeIndices.
size() > 1 &&
1805 ReturnAndArgTypeIndices.
back() == TypeIndex::Void()) {
1808 TypeIndex ReturnTypeIndex = TypeIndex::Void();
1810 if (!ReturnAndArgTypeIndices.
empty()) {
1811 auto ReturnAndArgTypesRef =
makeArrayRef(ReturnAndArgTypeIndices);
1812 ReturnTypeIndex = ReturnAndArgTypesRef.front();
1813 ArgTypeIndices = ReturnAndArgTypesRef.
drop_front();
1816 ArgListRecord ArgListRec(TypeRecordKind::ArgList, ArgTypeIndices);
1817 TypeIndex ArgListIndex = TypeTable.writeLeafType(ArgListRec);
1824 return TypeTable.writeLeafType(Procedure);
1830 bool IsStaticMethod,
1833 TypeIndex ClassType = getTypeIndex(ClassTy);
1839 TypeIndex ReturnTypeIndex = TypeIndex::Void();
1841 ReturnTypeIndex = getTypeIndex(ReturnAndArgs[Index++]);
1848 if (!IsStaticMethod && ReturnAndArgs.
size() >
Index) {
1850 dyn_cast_or_null<DIDerivedType>(ReturnAndArgs[Index].resolve())) {
1851 if (PtrTy->getTag() == dwarf::DW_TAG_pointer_type) {
1852 ThisTypeIndex = getTypeIndexForThisPtr(PtrTy, Ty);
1858 while (Index < ReturnAndArgs.
size())
1859 ArgTypeIndices.
push_back(getTypeIndex(ReturnAndArgs[Index++]));
1862 if (!ArgTypeIndices.
empty() && ArgTypeIndices.
back() == TypeIndex::Void())
1865 ArgListRecord ArgListRec(TypeRecordKind::ArgList, ArgTypeIndices);
1866 TypeIndex ArgListIndex = TypeTable.writeLeafType(ArgListRec);
1871 ArgTypeIndices.
size(), ArgListIndex, ThisAdjustment);
1872 return TypeTable.writeLeafType(MFR);
1876 unsigned VSlotCount =
1881 return TypeTable.writeLeafType(VFTSR);
1886 case DINode::FlagPrivate:
return MemberAccess::Private;
1887 case DINode::FlagPublic:
return MemberAccess::Public;
1888 case DINode::FlagProtected:
return MemberAccess::Protected;
1891 return RecordTag == dwarf::DW_TAG_class_type ? MemberAccess::Private
1892 : MemberAccess::Public;
1898 if (SP->isArtificial())
1899 return MethodOptions::CompilerGenerated;
1908 if (SP->getFlags() & DINode::FlagStaticMember)
1911 switch (SP->getVirtuality()) {
1912 case dwarf::DW_VIRTUALITY_none:
1914 case dwarf::DW_VIRTUALITY_virtual:
1915 return Introduced ? MethodKind::IntroducingVirtual : MethodKind::Virtual;
1916 case dwarf::DW_VIRTUALITY_pure_virtual:
1917 return Introduced ? MethodKind::PureIntroducingVirtual
1918 : MethodKind::PureVirtual;
1923 return MethodKind::Vanilla;
1929 case dwarf::DW_TAG_structure_type:
return TypeRecordKind::Struct;
1943 CO |= ClassOptions::HasUniqueName;
1949 if (ImmediateScope && isa<DICompositeType>(ImmediateScope))
1950 CO |= ClassOptions::Nested;
1956 if (Ty->
getTag() == dwarf::DW_TAG_enumeration_type) {
1957 if (ImmediateScope && isa<DISubprogram>(ImmediateScope))
1958 CO |= ClassOptions::Scoped;
1960 for (
const DIScope *Scope = ImmediateScope; Scope !=
nullptr;
1962 if (isa<DISubprogram>(Scope)) {
1963 CO |= ClassOptions::Scoped;
1974 case dwarf::DW_TAG_class_type:
1975 case dwarf::DW_TAG_structure_type:
1976 case dwarf::DW_TAG_union_type:
1977 case dwarf::DW_TAG_enumeration_type:
1983 if (
const auto *File = Ty->
getFile()) {
1985 TypeIndex SIDI = TypeTable.writeLeafType(SIDR);
1988 TypeTable.writeLeafType(USLR);
1995 unsigned EnumeratorCount = 0;
1998 CO |= ClassOptions::ForwardReference;
2001 ContinuationBuilder.
begin(ContinuationRecordKind::FieldList);
2005 if (
auto *
Enumerator = dyn_cast_or_null<DIEnumerator>(Element)) {
2013 FTI = TypeTable.insertRecord(ContinuationBuilder);
2020 TypeIndex EnumTI = TypeTable.writeLeafType(ER);
2022 addUDTSrcLine(Ty, EnumTI);
2056 void CodeViewDebug::clear() {
2057 assert(CurFn ==
nullptr);
2059 FnDebugInfo.clear();
2060 FileToFilepathMap.clear();
2063 TypeIndices.clear();
2064 CompleteTypeIndices.clear();
2065 ScopeGlobals.clear();
2071 Info.
Members.push_back({DDTy, 0});
2082 bool FullyResolved =
false;
2083 while (!FullyResolved) {
2085 case dwarf::DW_TAG_const_type:
2086 case dwarf::DW_TAG_volatile_type:
2089 Ty = cast<DIDerivedType>(Ty)->
getBaseType().resolve();
2092 FullyResolved =
true;
2101 ClassInfo NestedInfo = collectClassInfo(DCTy);
2111 for (
auto *Element : Elements) {
2116 if (
auto *SP = dyn_cast<DISubprogram>(Element)) {
2117 Info.
Methods[SP->getRawName()].push_back(SP);
2118 }
else if (
auto *DDTy = dyn_cast<DIDerivedType>(Element)) {
2119 if (DDTy->
getTag() == dwarf::DW_TAG_member) {
2120 collectMemberInfo(Info, DDTy);
2121 }
else if (DDTy->
getTag() == dwarf::DW_TAG_inheritance) {
2123 }
else if (DDTy->
getTag() == dwarf::DW_TAG_pointer_type &&
2124 DDTy->
getName() ==
"__vtbl_ptr_type") {
2125 Info.
VShapeTI = getTypeIndex(DDTy);
2126 }
else if (DDTy->
getTag() == dwarf::DW_TAG_typedef) {
2128 }
else if (DDTy->
getTag() == dwarf::DW_TAG_friend) {
2132 }
else if (
auto *Composite = dyn_cast<DICompositeType>(Element)) {
2156 auto I = CompleteTypeIndices.find(Ty);
2157 if (
I != CompleteTypeIndices.end() &&
I->second ==
TypeIndex())
2159 return getCompleteTypeIndex(Ty);
2170 TypeIndex FwdDeclTI = TypeTable.writeLeafType(CR);
2172 DeferredCompleteTypes.push_back(Ty);
2182 unsigned FieldCount;
2184 std::tie(FieldTI, VShapeTI, FieldCount, ContainsNestedClass) =
2185 lowerRecordFieldList(Ty);
2187 if (ContainsNestedClass)
2188 CO |= ClassOptions::ContainsNestedClass;
2196 TypeIndex ClassTI = TypeTable.writeLeafType(CR);
2198 addUDTSrcLine(Ty, ClassTI);
2208 return getCompleteTypeIndex(Ty);
2214 TypeIndex FwdDeclTI = TypeTable.writeLeafType(UR);
2216 DeferredCompleteTypes.push_back(Ty);
2223 unsigned FieldCount;
2225 std::tie(FieldTI, std::ignore, FieldCount, ContainsNestedClass) =
2226 lowerRecordFieldList(Ty);
2228 if (ContainsNestedClass)
2229 CO |= ClassOptions::ContainsNestedClass;
2234 UnionRecord UR(FieldCount, CO, FieldTI, SizeInBytes, FullName,
2236 TypeIndex UnionTI = TypeTable.writeLeafType(UR);
2238 addUDTSrcLine(Ty, UnionTI);
2245 std::tuple<TypeIndex, TypeIndex, unsigned, bool>
2251 unsigned MemberCount = 0;
2254 ContinuationBuilder.
begin(ContinuationRecordKind::FieldList);
2258 if (I->
getFlags() & DINode::FlagVirtual) {
2260 unsigned VBPtrOffset = I->getVBPtrOffset();
2263 auto RecordKind = (I->
getFlags() & DINode::FlagIndirectVirtualBase) == DINode::FlagIndirectVirtualBase
2264 ? TypeRecordKind::IndirectVirtualBaseClass
2265 : TypeRecordKind::VirtualBaseClass;
2268 getTypeIndex(I->getBaseType()), getVBPTypeIndex(), VBPtrOffset,
2275 "bases must be on byte boundaries");
2277 getTypeIndex(I->getBaseType()),
2287 TypeIndex MemberBaseType = getTypeIndex(Member->getBaseType());
2300 if ((Member->
getFlags() & DINode::FlagArtificial) &&
2302 VFPtrRecord VFPR(getTypeIndex(Member->getBaseType()));
2309 uint64_t MemberOffsetInBits =
2312 uint64_t StartBitOffset = MemberOffsetInBits;
2313 if (
const auto *CI =
2314 dyn_cast_or_null<ConstantInt>(Member->getStorageOffsetInBits())) {
2315 MemberOffsetInBits = CI->getZExtValue() + MemberInfo.
BaseOffset;
2317 StartBitOffset -= MemberOffsetInBits;
2320 MemberBaseType = TypeTable.writeLeafType(BFR);
2322 uint64_t MemberOffsetInBytes = MemberOffsetInBits / 8;
2330 for (
auto &MethodItr : Info.
Methods) {
2333 std::vector<OneMethodRecord> Methods;
2335 TypeIndex MethodType = getMemberFunctionType(SP, Ty);
2336 bool Introduced = SP->getFlags() & DINode::FlagIntroducedVirtual;
2338 unsigned VFTableOffset = -1;
2340 VFTableOffset = SP->getVirtualIndex() * getPointerSizeInBytes();
2348 assert(!Methods.empty() &&
"Empty methods map entry");
2349 if (Methods.size() == 1)
2355 TypeIndex MethodList = TypeTable.writeLeafType(MOLR);
2369 TypeIndex FieldTI = TypeTable.insertRecord(ContinuationBuilder);
2370 return std::make_tuple(FieldTI, Info.
VShapeTI, MemberCount,
2374 TypeIndex CodeViewDebug::getVBPTypeIndex() {
2375 if (!VBPType.getIndex()) {
2378 TypeIndex ModifiedTI = TypeTable.writeLeafType(MR);
2380 PointerKind PK = getPointerSizeInBytes() == 8 ? PointerKind::Near64
2381 : PointerKind::Near32;
2384 PointerRecord PR(ModifiedTI, PK, PM, PO, getPointerSizeInBytes());
2385 VBPType = TypeTable.writeLeafType(PR);
2397 return TypeIndex::Void();
2402 auto I = TypeIndices.find({Ty, ClassTy});
2403 if (
I != TypeIndices.end())
2406 TypeLoweringScope S(*
this);
2408 return recordTypeIndexForDINode(Ty, TI, ClassTy);
2412 CodeViewDebug::getTypeIndexForThisPtr(
const DIDerivedType *PtrTy,
2414 assert(PtrTy->
getTag() == dwarf::DW_TAG_pointer_type &&
2415 "this type must be a pointer type");
2418 if (SubroutineTy->
getFlags() & DINode::DIFlags::FlagLValueReference)
2419 Options = PointerOptions::LValueRefThisPointer;
2420 else if (SubroutineTy->
getFlags() & DINode::DIFlags::FlagRValueReference)
2421 Options = PointerOptions::RValueRefThisPointer;
2428 auto I = TypeIndices.find({PtrTy, SubroutineTy});
2429 if (
I != TypeIndices.end())
2432 TypeLoweringScope S(*
this);
2433 TypeIndex TI = lowerTypePointer(PtrTy, Options);
2434 return recordTypeIndexForDINode(PtrTy, TI, SubroutineTy);
2440 getPointerSizeInBytes() == 8 ? PointerKind::Near64
2441 : PointerKind::Near32,
2444 return TypeTable.writeLeafType(PR);
2452 return TypeIndex::Void();
2457 if (Ty->
getTag() == dwarf::DW_TAG_typedef)
2458 (
void)getTypeIndex(Ty);
2459 while (Ty->
getTag() == dwarf::DW_TAG_typedef)
2460 Ty = cast<DIDerivedType>(Ty)->getBaseType().
resolve();
2465 case dwarf::DW_TAG_class_type:
2466 case dwarf::DW_TAG_structure_type:
2467 case dwarf::DW_TAG_union_type:
2470 return getTypeIndex(Ty);
2474 const auto *CTy = cast<DICompositeType>(Ty);
2475 auto InsertResult = CompleteTypeIndices.insert({CTy,
TypeIndex()});
2476 if (!InsertResult.second)
2477 return InsertResult.first->second;
2479 TypeLoweringScope S(*
this);
2485 if (!CTy->getName().empty() || !CTy->getIdentifier().empty()) {
2486 TypeIndex FwdDeclTI = getTypeIndex(CTy);
2491 if (CTy->isForwardDecl())
2496 switch (CTy->getTag()) {
2497 case dwarf::DW_TAG_class_type:
2498 case dwarf::DW_TAG_structure_type:
2499 TI = lowerCompleteTypeClass(CTy);
2501 case dwarf::DW_TAG_union_type:
2502 TI = lowerCompleteTypeUnion(CTy);
2512 CompleteTypeIndices[CTy] = TI;
2520 void CodeViewDebug::emitDeferredCompleteTypes() {
2522 while (!DeferredCompleteTypes.empty()) {
2523 std::swap(DeferredCompleteTypes, TypesToEmit);
2525 getCompleteTypeIndex(RecordTy);
2526 TypesToEmit.clear();
2530 void CodeViewDebug::emitLocalVariableList(
const FunctionInfo &FI,
2534 for (
const LocalVariable &L : Locals)
2535 if (L.DIVar->isParameter())
2537 llvm::sort(Params, [](
const LocalVariable *L,
const LocalVariable *R) {
2538 return L->DIVar->getArg() < R->DIVar->getArg();
2540 for (
const LocalVariable *L : Params)
2541 emitLocalVariable(FI, *L);
2544 for (
const LocalVariable &L : Locals)
2545 if (!L.DIVar->isParameter())
2546 emitLocalVariable(FI, L);
2551 template <
typename T>
2554 BytePrefix.
resize(2 +
sizeof(
T));
2556 memcpy(&BytePrefix[0], &SymKindLE, 2);
2557 memcpy(&BytePrefix[2], &DefRangeHeader,
sizeof(
T));
2560 void CodeViewDebug::emitLocalVariable(
const FunctionInfo &FI,
2561 const LocalVariable &Var) {
2563 MCSymbol *LocalEnd = beginSymbolRecord(SymbolKind::S_LOCAL);
2566 if (Var.DIVar->isParameter())
2567 Flags |= LocalSymFlags::IsParameter;
2568 if (Var.DefRanges.empty())
2569 Flags |= LocalSymFlags::IsOptimizedOut;
2571 OS.AddComment(
"TypeIndex");
2573 ? getTypeIndexForReferenceTo(Var.DIVar->getType())
2574 : getCompleteTypeIndex(Var.DIVar->getType());
2576 OS.AddComment(
"Flags");
2577 OS.EmitIntValue(static_cast<uint16_t>(Flags), 2);
2580 endSymbolRecord(LocalEnd);
2586 for (
const LocalVarDefRange &DefRange : Var.DefRanges) {
2588 if (DefRange.InMemory) {
2589 int Offset = DefRange.DataOffset;
2590 unsigned Reg = DefRange.CVRegister;
2596 Reg =
unsigned(RegisterId::VFRAME);
2597 Offset += FI.OffsetAdjustment;
2605 (
bool(Flags & LocalSymFlags::IsParameter)
2606 ? (EncFP == FI.EncodedParamFramePtrReg)
2607 : (EncFP == FI.EncodedLocalFramePtrReg))) {
2611 uint16_t RegRelFlags = 0;
2612 if (DefRange.IsSubfield) {
2613 RegRelFlags = DefRangeRegisterRelSym::IsSubfieldFlag |
2614 (DefRange.StructOffset
2615 << DefRangeRegisterRelSym::OffsetInParentShift);
2619 DRHdr.
Flags = RegRelFlags;
2624 assert(DefRange.DataOffset == 0 &&
"unexpected offset into register");
2625 if (DefRange.IsSubfield) {
2627 DRHdr.
Register = DefRange.CVRegister;
2633 DRHdr.
Register = DefRange.CVRegister;
2638 OS.EmitCVDefRangeDirective(DefRange.Ranges, BytePrefix);
2643 const FunctionInfo& FI) {
2644 for (LexicalBlock *Block : Blocks)
2645 emitLexicalBlock(*Block, FI);
2650 void CodeViewDebug::emitLexicalBlock(
const LexicalBlock &Block,
2651 const FunctionInfo& FI) {
2652 MCSymbol *RecordEnd = beginSymbolRecord(SymbolKind::S_BLOCK32);
2653 OS.AddComment(
"PtrParent");
2654 OS.EmitIntValue(0, 4);
2655 OS.AddComment(
"PtrEnd");
2656 OS.EmitIntValue(0, 4);
2657 OS.AddComment(
"Code size");
2658 OS.emitAbsoluteSymbolDiff(Block.End, Block.Begin, 4);
2659 OS.AddComment(
"Function section relative address");
2660 OS.EmitCOFFSecRel32(Block.Begin, 0);
2661 OS.AddComment(
"Function section index");
2662 OS.EmitCOFFSectionIndex(FI.Begin);
2663 OS.AddComment(
"Lexical block name");
2665 endSymbolRecord(RecordEnd);
2668 emitLocalVariableList(FI, Block.Locals);
2669 emitGlobalVariableList(Block.Globals);
2672 emitLexicalBlockList(Block.Children, FI);
2675 emitEndSymbolRecord(SymbolKind::S_END);
2680 void CodeViewDebug::collectLexicalBlockInfo(
2686 collectLexicalBlockInfo(*Scope, Blocks, Locals, Globals);
2691 void CodeViewDebug::collectLexicalBlockInfo(
2701 bool IgnoreScope =
false;
2702 auto LI = ScopeVariables.find(&Scope);
2704 LI != ScopeVariables.
end() ? &LI->second :
nullptr;
2707 GI != ScopeGlobals.
end() ? GI->second.get() :
nullptr;
2712 if (!Locals && !Globals)
2752 auto BlockInsertion = CurFn->LexicalBlocks.insert({DILB, LexicalBlock()});
2753 if (!BlockInsertion.second)
2758 const InsnRange &Range = Ranges.front();
2759 assert(Range.first && Range.second);
2760 LexicalBlock &Block = BlockInsertion.first->second;
2763 assert(Block.Begin &&
"missing label for scope begin");
2764 assert(Block.End &&
"missing label for scope end");
2767 Block.Locals = std::move(*Locals);
2769 Block.Globals = std::move(*Globals);
2779 assert(FnDebugInfo.count(&GV));
2780 assert(CurFn == FnDebugInfo[&GV].
get());
2786 collectLexicalBlockInfo(*CFS,
2794 ScopeVariables.clear();
2798 if (!CurFn->HaveLineInfo && !GV.
getSubprogram()->isThunk()) {
2799 FnDebugInfo.erase(&GV);
2823 for (
const auto &NextMI : *MI->
getParent()) {
2824 if (NextMI.isDebugInstr())
2826 DL = NextMI.getDebugLoc();
2837 maybeRecordLocation(DL,
Asm->
MF);
2843 OS.EmitIntValue(
unsigned(Kind), 4);
2844 OS.AddComment(
"Subsection size");
2845 OS.emitAbsoluteSymbolDiff(EndLabel, BeginLabel, 4);
2846 OS.EmitLabel(BeginLabel);
2850 void CodeViewDebug::endCVSubsection(
MCSymbol *EndLabel) {
2851 OS.EmitLabel(EndLabel);
2853 OS.EmitValueToAlignment(4);
2858 if (EE.Value == SymKind)
2866 OS.AddComment(
"Record length");
2867 OS.emitAbsoluteSymbolDiff(EndLabel, BeginLabel, 2);
2868 OS.EmitLabel(BeginLabel);
2869 if (OS.isVerboseAsm())
2871 OS.EmitIntValue(
unsigned(SymKind), 2);
2875 void CodeViewDebug::endSymbolRecord(
MCSymbol *SymEnd) {
2880 OS.EmitValueToAlignment(4);
2881 OS.EmitLabel(SymEnd);
2884 void CodeViewDebug::emitEndSymbolRecord(
SymbolKind EndKind) {
2885 OS.AddComment(
"Record length");
2886 OS.EmitIntValue(2, 2);
2887 if (OS.isVerboseAsm())
2889 OS.EmitIntValue(
unsigned(EndKind), 2);
2892 void CodeViewDebug::emitDebugInfoForUDTs(
2893 ArrayRef<std::pair<std::string, const DIType *>> UDTs) {
2894 for (
const auto &UDT : UDTs) {
2898 MCSymbol *UDTRecordEnd = beginSymbolRecord(SymbolKind::S_UDT);
2899 OS.AddComment(
"Type");
2900 OS.EmitIntValue(getCompleteTypeIndex(T).getIndex(), 4);
2902 endSymbolRecord(UDTRecordEnd);
2906 void CodeViewDebug::collectGlobalVariableInfo() {
2911 GV.getDebugInfo(GVEs);
2912 for (
const auto *GVE : GVEs)
2913 GlobalMap[GVE] = &GV;
2918 const auto *
CU = cast<DICompileUnit>(Node);
2919 for (
const auto *GVE :
CU->getGlobalVariables()) {
2920 const auto *GV = GlobalMap.
lookup(GVE);
2926 if (Scope && isa<DILocalScope>(Scope)) {
2929 auto Insertion = ScopeGlobals.
insert(
2930 {Scope, std::unique_ptr<GlobalVariableList>()});
2931 if (Insertion.second)
2932 Insertion.first->second = llvm::make_unique<GlobalVariableList>();
2933 VariableList = Insertion.first->second.get();
2936 VariableList = &ComdatVariables;
2939 VariableList = &GlobalVariables;
2940 CVGlobalVariable CVGV = {DIGV, GV};
2946 void CodeViewDebug::emitDebugInfoForGlobals() {
2950 switchToDebugSectionForSymbol(
nullptr);
2951 if (!GlobalVariables.empty()) {
2952 OS.AddComment(
"Symbol subsection for globals");
2953 MCSymbol *EndLabel = beginCVSubsection(DebugSubsectionKind::Symbols);
2954 emitGlobalVariableList(GlobalVariables);
2955 endCVSubsection(EndLabel);
2960 for (
const CVGlobalVariable &CVGV : ComdatVariables) {
2962 OS.AddComment(
"Symbol subsection for " +
2964 switchToDebugSectionForSymbol(GVSym);
2965 MCSymbol *EndLabel = beginCVSubsection(DebugSubsectionKind::Symbols);
2967 emitDebugInfoForGlobal(CVGV.DIGV, CVGV.GV, GVSym);
2968 endCVSubsection(EndLabel);
2972 void CodeViewDebug::emitDebugInfoForRetainedTypes() {
2975 for (
auto *Ty : cast<DICompileUnit>(Node)->getRetainedTypes()) {
2976 if (
DIType *RT = dyn_cast<DIType>(Ty)) {
2986 for (
const CVGlobalVariable &CVGV : Globals) {
2989 emitDebugInfoForGlobal(CVGV.DIGV, CVGV.GV, GVSym);
3000 : SymbolKind::S_GTHREAD32)
3002 : SymbolKind::S_GDATA32);
3003 MCSymbol *DataEnd = beginSymbolRecord(DataSym);
3004 OS.AddComment(
"Type");
3005 OS.EmitIntValue(getCompleteTypeIndex(DIGV->
getType()).getIndex(), 4);
3006 OS.AddComment(
"DataOffset");
3007 OS.EmitCOFFSecRel32(GVSym, 0);
3008 OS.AddComment(
"Segment");
3009 OS.EmitCOFFSectionIndex(GVSym);
3010 OS.AddComment(
"Name");
3011 const unsigned LengthOfDataRecord = 12;
3013 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
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
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.
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
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE size_t size() const
size - Get the string size.
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
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE const char * data() const
data - Get a pointer to the start of the string (which may not be null terminated).
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.
amdgpu Simplify well known AMD library false Value Value const Twine & Name
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.
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.
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()))
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE bool startswith(StringRef Prefix) const
Check if this string starts with the given Prefix.
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
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE bool empty() const
empty - Check if the string is empty.
NamedMDNode * getNamedMetadata(const Twine &Name) const
Return the first NamedMDNode in the module with the specified name.
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")
LLVM_ATTRIBUTE_ALWAYS_INLINE iterator begin()
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.
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE StringRef drop_front(size_t N=1) const
Return a StringRef equal to 'this' but with the first N elements dropped.
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)
LLVM_ATTRIBUTE_ALWAYS_INLINE iterator end()
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.
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
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
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE StringRef take_front(size_t N=1) const
Return a StringRef equal to 'this' but with only the first N elements remaining.
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