40 using namespace llvm::codeview;
41 using namespace llvm::msf;
59 std::string &Filepath = FileToFilepathMap[
File];
60 if (!Filepath.empty())
69 if (Filename.find(
':') == 1)
72 Filepath = (Dir +
"\\" + Filename).str();
77 std::replace(Filepath.begin(), Filepath.end(),
'/',
'\\');
81 while ((Cursor = Filepath.find(
"\\.\\", Cursor)) != std::string::npos)
82 Filepath.erase(Cursor, 2);
87 while ((Cursor = Filepath.find(
"\\..\\", Cursor)) != std::string::npos) {
92 size_t PrevSlash = Filepath.
rfind(
'\\', Cursor - 1);
93 if (PrevSlash == std::string::npos)
97 Filepath.erase(PrevSlash, Cursor + 3 - PrevSlash);
104 while ((Cursor = Filepath.find(
"\\\\", Cursor)) != std::string::npos)
105 Filepath.erase(Cursor, 1);
110 unsigned CodeViewDebug::maybeRecordFile(
const DIFile *
F) {
111 unsigned NextId = FileIdMap.size() + 1;
112 auto Insertion = FileIdMap.insert(std::make_pair(F, NextId));
113 if (Insertion.second) {
118 assert(Success &&
".cv_file directive failed");
120 return Insertion.first->second;
123 CodeViewDebug::InlineSite &
124 CodeViewDebug::getInlineSite(
const DILocation *InlinedAt,
126 auto SiteInsertion = CurFn->InlineSites.insert({InlinedAt, InlineSite()});
127 InlineSite *Site = &SiteInsertion.first->second;
128 if (SiteInsertion.second) {
129 unsigned ParentFuncId = CurFn->FuncId;
130 if (
const DILocation *OuterIA = InlinedAt->getInlinedAt())
132 getInlineSite(OuterIA, InlinedAt->getScope()->getSubprogram())
135 Site->SiteFuncId = NextFuncId++;
137 Site->SiteFuncId, ParentFuncId, maybeRecordFile(InlinedAt->getFile()),
138 InlinedAt->getLine(), InlinedAt->getColumn(),
SMLoc());
139 Site->Inlinee = Inlinee;
140 InlinedSubprograms.insert(Inlinee);
141 getFuncIdForSubprogram(Inlinee);
148 if (!ScopeName.
empty())
151 switch (Scope->
getTag()) {
152 case dwarf::DW_TAG_enumeration_type:
153 case dwarf::DW_TAG_class_type:
154 case dwarf::DW_TAG_structure_type:
155 case dwarf::DW_TAG_union_type:
156 return "<unnamed-tag>";
157 case dwarf::DW_TAG_namespace:
158 return "`anonymous namespace'";
167 while (Scope !=
nullptr) {
168 if (ClosestSubprogram ==
nullptr)
171 if (!ScopeName.empty())
172 QualifiedNameComponents.
push_back(ScopeName);
175 return ClosestSubprogram;
180 std::string FullyQualifiedName;
182 FullyQualifiedName.append(QualifiedNameComponent);
183 FullyQualifiedName.append(
"::");
185 FullyQualifiedName.append(TypeName);
186 return FullyQualifiedName;
200 if (
CVD.TypeEmissionLevel == 1)
201 CVD.emitDeferredCompleteTypes();
202 --
CVD.TypeEmissionLevel;
214 if (!Scope || isa<DIFile>(Scope))
217 assert(!isa<DIType>(Scope) &&
"shouldn't make a namespace scope for a type");
220 auto I = TypeIndices.find({Scope,
nullptr});
221 if (
I != TypeIndices.end())
228 return recordTypeIndexForDINode(Scope, TI);
235 auto I = TypeIndices.find({SP,
nullptr});
236 if (
I != TypeIndices.end())
241 StringRef DisplayName = SP->getDisplayName().split(
'<').first;
245 if (
const auto *Class = dyn_cast_or_null<DICompositeType>(Scope)) {
249 TypeIndex ClassType = getTypeIndex(Class);
255 TypeIndex ParentScope = getScopeIndex(Scope);
256 FuncIdRecord FuncId(ParentScope, getTypeIndex(SP->getType()), DisplayName);
260 return recordTypeIndexForDINode(SP, TI);
267 if (SP->getDeclaration())
268 SP = SP->getDeclaration();
269 assert(!SP->getDeclaration() &&
"should use declaration as key");
273 auto I = TypeIndices.find({SP, Class});
274 if (I != TypeIndices.end())
280 TypeLoweringScope S(*
this);
282 lowerTypeMemberFunction(SP->getType(), Class, SP->getThisAdjustment());
283 return recordTypeIndexForDINode(SP, TI, Class);
289 auto InsertResult = TypeIndices.insert({{Node, ClassTy}, TI});
291 assert(InsertResult.second &&
"DINode was already assigned a type index");
295 unsigned CodeViewDebug::getPointerSizeInBytes() {
299 void CodeViewDebug::recordLocalVariable(LocalVariable &&Var,
304 InlineSite &Site = getInlineSite(InlinedAt, Inlinee);
305 Site.InlinedLocals.emplace_back(Var);
308 CurFn->Locals.emplace_back(Var);
319 void CodeViewDebug::maybeRecordLocation(
const DebugLoc &DL,
322 if (DL == CurFn->LastLoc)
331 if (LI.getStartLine() != DL.
getLine() || LI.isAlwaysStepInto() ||
332 LI.isNeverStepInto())
336 if (CI.getStartColumn() != DL.
getCol())
339 if (!CurFn->HaveLineInfo)
340 CurFn->HaveLineInfo =
true;
342 if (CurFn->LastLoc.get() && CurFn->LastLoc->getFile() == DL->getFile())
343 FileId = CurFn->LastFileId;
345 FileId = CurFn->LastFileId = maybeRecordFile(DL->getFile());
348 unsigned FuncId = CurFn->FuncId;
349 if (
const DILocation *SiteLoc = DL->getInlinedAt()) {
355 getInlineSite(SiteLoc, Loc->getScope()->getSubprogram()).SiteFuncId;
358 bool FirstLoc =
true;
359 while ((SiteLoc = Loc->getInlinedAt())) {
361 getInlineSite(SiteLoc, Loc->getScope()->getSubprogram());
372 DL->getFilename(),
SMLoc());
375 void CodeViewDebug::emitCodeViewMagicVersion() {
394 switchToDebugSectionForSymbol(
nullptr);
396 MCSymbol *CompilerInfo = beginCVSubsection(ModuleSubstreamKind::Symbols);
397 emitCompilerInformation();
398 endCVSubsection(CompilerInfo);
400 emitInlineeLinesSubsection();
403 for (
auto &
P : FnDebugInfo)
404 if (!
P.first->isDeclarationForLinker())
405 emitDebugInfoForFunction(
P.first,
P.second);
408 setCurrentSubprogram(
nullptr);
409 emitDebugInfoForGlobals();
412 emitDebugInfoForRetainedTypes();
416 switchToDebugSectionForSymbol(
nullptr);
419 if (!GlobalUDTs.empty()) {
420 MCSymbol *SymbolsEnd = beginCVSubsection(ModuleSubstreamKind::Symbols);
421 emitDebugInfoForUDTs(GlobalUDTs);
422 endCVSubsection(SymbolsEnd);
426 OS.
AddComment(
"File index to string table offset subsection");
435 emitTypeInformation();
445 unsigned MaxFixedRecordLength = 0xF00;
452 void CodeViewDebug::emitTypeInformation() {
458 if (TypeTable.
empty())
463 emitCodeViewMagicVersion();
467 CommentPrefix +=
'\t';
469 CommentPrefix +=
' ';
480 SP.setPrefix(CommentPrefix);
482 Error E = CVTD.dump(Record, TDV);
491 CommentOS.str().drop_front(CommentPrefix.
size() - 1).rtrim());
501 Error E = Reader.readArray(Types, Reader.getLength());
521 case dwarf::DW_LANG_C:
522 case dwarf::DW_LANG_C89:
523 case dwarf::DW_LANG_C99:
524 case dwarf::DW_LANG_C11:
525 case dwarf::DW_LANG_ObjC:
527 case dwarf::DW_LANG_C_plus_plus:
528 case dwarf::DW_LANG_C_plus_plus_03:
529 case dwarf::DW_LANG_C_plus_plus_11:
530 case dwarf::DW_LANG_C_plus_plus_14:
532 case dwarf::DW_LANG_Fortran77:
533 case dwarf::DW_LANG_Fortran90:
534 case dwarf::DW_LANG_Fortran03:
535 case dwarf::DW_LANG_Fortran08:
537 case dwarf::DW_LANG_Pascal83:
539 case dwarf::DW_LANG_Cobol74:
540 case dwarf::DW_LANG_Cobol85:
542 case dwarf::DW_LANG_Java:
561 for (
const char C : Name) {
564 V.Part[
N] += C -
'0';
565 }
else if (C ==
'.') {
577 case Triple::ArchType::x86:
578 return CPUType::Pentium3;
579 case Triple::ArchType::x86_64:
581 case Triple::ArchType::thumb:
582 return CPUType::Thumb;
591 void CodeViewDebug::emitCompilerInformation() {
604 const auto *CU = cast<DICompileUnit>(Node);
607 Flags = MapDWLangToCVLang(CU->getSourceLanguage());
618 StringRef CompilerVersion = CU->getProducer();
619 Version FrontVer = parseVersion(CompilerVersion);
621 for (
int N = 0; N < 4; ++
N)
627 int Major = 1000 * LLVM_VERSION_MAJOR +
628 10 * LLVM_VERSION_MINOR +
631 Major = std::min<int>(Major, std::numeric_limits<uint16_t>::max());
632 Version BackVer = {{ Major, 0, 0, 0 }};
634 for (
int N = 0; N < 4; ++
N)
637 OS.
AddComment(
"Null-terminated compiler version string");
643 void CodeViewDebug::emitInlineeLinesSubsection() {
644 if (InlinedSubprograms.empty())
648 MCSymbol *InlineEnd = beginCVSubsection(ModuleSubstreamKind::InlineeLines);
653 OS.
EmitIntValue(
unsigned(InlineeLinesSignature::Normal), 4);
656 assert(TypeIndices.count({SP,
nullptr}));
657 TypeIndex InlineeIdx = TypeIndices[{SP,
nullptr}];
660 unsigned FileId = maybeRecordFile(SP->
getFile());
661 OS.
AddComment(
"Inlined function " + SP->getDisplayName() +
" starts at " +
666 unsigned FileOffset = (FileId - 1) * 8;
667 OS.
AddComment(
"Type index of inlined function");
669 OS.
AddComment(
"Offset into filechecksum table");
675 endCVSubsection(InlineEnd);
678 void CodeViewDebug::emitInlinedCallSite(
const FunctionInfo &FI,
680 const InlineSite &Site) {
684 assert(TypeIndices.count({Site.Inlinee,
nullptr}));
685 TypeIndex InlineeIdx = TypeIndices[{Site.Inlinee,
nullptr}];
688 OS.AddComment(
"Record length");
689 OS.emitAbsoluteSymbolDiff(InlineEnd, InlineBegin, 2);
690 OS.EmitLabel(InlineBegin);
691 OS.AddComment(
"Record kind: S_INLINESITE");
692 OS.EmitIntValue(SymbolKind::S_INLINESITE, 2);
694 OS.AddComment(
"PtrParent");
695 OS.EmitIntValue(0, 4);
696 OS.AddComment(
"PtrEnd");
697 OS.EmitIntValue(0, 4);
698 OS.AddComment(
"Inlinee type index");
699 OS.EmitIntValue(InlineeIdx.
getIndex(), 4);
701 unsigned FileId = maybeRecordFile(Site.Inlinee->getFile());
702 unsigned StartLineNum = Site.Inlinee->getLine();
704 OS.EmitCVInlineLinetableDirective(Site.SiteFuncId, FileId, StartLineNum,
707 OS.EmitLabel(InlineEnd);
709 emitLocalVariableList(Site.InlinedLocals);
712 for (
const DILocation *ChildSite : Site.ChildSites) {
713 auto I = FI.InlineSites.find(ChildSite);
714 assert(I != FI.InlineSites.end() &&
715 "child site not in function inline site map");
716 emitInlinedCallSite(FI, ChildSite, I->second);
720 OS.AddComment(
"Record length");
721 OS.EmitIntValue(2, 2);
722 OS.AddComment(
"Record kind: S_INLINESITE_END");
723 OS.EmitIntValue(SymbolKind::S_INLINESITE_END, 2);
726 void CodeViewDebug::switchToDebugSectionForSymbol(
const MCSymbol *GVSym) {
742 if (ComdatDebugSections.insert(DebugSec).second)
743 emitCodeViewMagicVersion();
746 void CodeViewDebug::emitDebugInfoForFunction(
const Function *GV,
754 switchToDebugSectionForSymbol(Fn);
756 std::string FuncName;
759 setCurrentSubprogram(SP);
763 if (!SP->getDisplayName().empty())
768 if (FuncName.empty())
773 MCSymbol *SymbolsEnd = beginCVSubsection(ModuleSubstreamKind::Symbols);
806 OS.
AddComment(
"Function section relative address");
818 emitLocalVariableList(FI.Locals);
823 for (
const DILocation *InlinedAt : FI.ChildSites) {
824 auto I = FI.InlineSites.find(InlinedAt);
825 assert(I != FI.InlineSites.end() &&
826 "child site not in function inline site map");
827 emitInlinedCallSite(FI, InlinedAt, I->second);
831 emitDebugInfoForUDTs(LocalUDTs);
837 OS.
EmitIntValue(
unsigned(SymbolKind::S_PROC_ID_END), 2);
839 endCVSubsection(SymbolsEnd);
845 CodeViewDebug::LocalVarDefRange
846 CodeViewDebug::createDefRangeMem(uint16_t CVRegister,
int Offset) {
850 assert(DR.DataOffset == Offset &&
"truncation");
853 DR.CVRegister = CVRegister;
857 CodeViewDebug::LocalVarDefRange
858 CodeViewDebug::createDefRangeGeneral(uint16_t CVRegister,
bool InMemory,
859 int Offset,
bool IsSubfield,
860 uint16_t StructOffset) {
862 DR.InMemory = InMemory;
864 DR.IsSubfield = IsSubfield;
865 DR.StructOffset = StructOffset;
866 DR.CVRegister = CVRegister;
870 void CodeViewDebug::collectVariableInfoFromMFTable(
880 assert(
VI.Var->isValidLocationForIntrinsic(
VI.Loc) &&
881 "Expected inlined-at fields to agree");
883 Processed.
insert(InlinedVariable(
VI.Var,
VI.Loc->getInlinedAt()));
891 unsigned FrameReg = 0;
896 LocalVarDefRange DefRange = createDefRangeMem(CVReg, FrameOffset);
901 DefRange.Ranges.emplace_back(Begin, End);
906 Var.DefRanges.emplace_back(std::move(DefRange));
907 recordLocalVariable(std::move(Var),
VI.Loc->getInlinedAt());
911 void CodeViewDebug::collectVariableInfo(
const DISubprogram *SP) {
914 collectVariableInfoFromMFTable(Processed);
919 InlinedVariable IV = I.first;
920 if (Processed.
count(IV))
926 const auto &Ranges = I.second;
941 for (
auto I = Ranges.begin(), E = Ranges.end(); I !=
E; ++
I) {
946 bool IsSubfield =
false;
947 unsigned StructOffset = 0;
951 if (DIExpr && Fragment) {
953 StructOffset = Fragment->OffsetInBits / 8;
954 }
else if (DIExpr && DIExpr->getNumElements() > 0) {
973 DR.CVRegister = CVReg;
974 DR.InMemory = InMemory;
976 DR.IsSubfield = IsSubfield;
977 DR.StructOffset = StructOffset;
979 if (Var.DefRanges.empty() ||
980 Var.DefRanges.back().isDifferentLocation(DR)) {
981 Var.DefRanges.emplace_back(std::move(DR));
991 auto J = std::next(I);
1004 Var.DefRanges.
back().Ranges;
1005 if (!Ranges.
empty() && Ranges.
back().second == Begin)
1013 recordLocalVariable(std::move(Var), InlinedAt);
1018 assert(!CurFn &&
"Can't process two functions at once!");
1026 assert(FnDebugInfo.count(GV) ==
false);
1027 CurFn = &FnDebugInfo[GV];
1028 CurFn->FuncId = NextFuncId++;
1038 bool EmptyPrologue =
true;
1039 for (
const auto &
MBB : *MF) {
1040 for (
const auto &
MI :
MBB) {
1043 PrologEndLoc =
MI.getDebugLoc();
1045 }
else if (!
MI.isDebugValue()) {
1046 EmptyPrologue =
false;
1052 if (PrologEndLoc && !EmptyPrologue) {
1054 maybeRecordLocation(FnStartDL, MF);
1067 std::string FullyQualifiedName =
1070 if (ClosestSubprogram ==
nullptr)
1071 GlobalUDTs.emplace_back(std::move(FullyQualifiedName), TI);
1072 else if (ClosestSubprogram == CurrentSubprogram)
1073 LocalUDTs.emplace_back(std::move(FullyQualifiedName), TI);
1086 case dwarf::DW_TAG_array_type:
1087 return lowerTypeArray(cast<DICompositeType>(Ty));
1088 case dwarf::DW_TAG_typedef:
1089 return lowerTypeAlias(cast<DIDerivedType>(Ty));
1090 case dwarf::DW_TAG_base_type:
1091 return lowerTypeBasic(cast<DIBasicType>(Ty));
1092 case dwarf::DW_TAG_pointer_type:
1093 if (cast<DIDerivedType>(Ty)->
getName() ==
"__vtbl_ptr_type")
1094 return lowerTypeVFTableShape(cast<DIDerivedType>(Ty));
1096 case dwarf::DW_TAG_reference_type:
1097 case dwarf::DW_TAG_rvalue_reference_type:
1098 return lowerTypePointer(cast<DIDerivedType>(Ty));
1099 case dwarf::DW_TAG_ptr_to_member_type:
1100 return lowerTypeMemberPointer(cast<DIDerivedType>(Ty));
1101 case dwarf::DW_TAG_const_type:
1102 case dwarf::DW_TAG_volatile_type:
1104 return lowerTypeModifier(cast<DIDerivedType>(Ty));
1105 case dwarf::DW_TAG_subroutine_type:
1109 return lowerTypeMemberFunction(cast<DISubroutineType>(Ty), ClassTy,
1112 return lowerTypeFunction(cast<DISubroutineType>(Ty));
1113 case dwarf::DW_TAG_enumeration_type:
1114 return lowerTypeEnum(cast<DICompositeType>(Ty));
1115 case dwarf::DW_TAG_class_type:
1116 case dwarf::DW_TAG_structure_type:
1117 return lowerTypeClass(cast<DICompositeType>(Ty));
1118 case dwarf::DW_TAG_union_type:
1119 return lowerTypeUnion(cast<DICompositeType>(Ty));
1127 DITypeRef UnderlyingTypeRef = Ty->getBaseType();
1128 TypeIndex UnderlyingTypeIndex = getTypeIndex(UnderlyingTypeRef);
1131 addToUDTs(Ty, UnderlyingTypeIndex);
1133 if (UnderlyingTypeIndex ==
TypeIndex(SimpleTypeKind::Int32Long) &&
1134 TypeName ==
"HRESULT")
1135 return TypeIndex(SimpleTypeKind::HResult);
1136 if (UnderlyingTypeIndex ==
TypeIndex(SimpleTypeKind::UInt16Short) &&
1137 TypeName ==
"wchar_t")
1138 return TypeIndex(SimpleTypeKind::WideCharacter);
1140 return UnderlyingTypeIndex;
1145 TypeIndex ElementTypeIndex = getTypeIndex(ElementTypeRef);
1169 bool PartiallyIncomplete =
false;
1171 PartiallyIncomplete =
true;
1176 for (
int i = Elements.size() - 1;
i >= 0; --
i) {
1177 const DINode *Element = Elements[
i];
1178 assert(Element->
getTag() == dwarf::DW_TAG_subrange_type);
1180 const DISubrange *Subrange = cast<DISubrange>(Element);
1181 assert(Subrange->getLowerBound() == 0 &&
1182 "codeview doesn't support subranges with lower bounds");
1183 int64_t Count = Subrange->getCount();
1190 PartiallyIncomplete =
true;
1194 ElementSize *= Count;
1198 uint64_t ArraySize =
1199 (
i == 0 && ElementSize == 0) ? Ty->
getSizeInBits() / 8 : ElementSize;
1202 ArrayRecord AR(ElementTypeIndex, IndexType, ArraySize, Name);
1206 (void)PartiallyIncomplete;
1209 return ElementTypeIndex;
1222 case dwarf::DW_ATE_address:
1225 case dwarf::DW_ATE_boolean:
1227 case 1: STK = SimpleTypeKind::Boolean8;
break;
1228 case 2: STK = SimpleTypeKind::Boolean16;
break;
1229 case 4: STK = SimpleTypeKind::Boolean32;
break;
1230 case 8: STK = SimpleTypeKind::Boolean64;
break;
1231 case 16: STK = SimpleTypeKind::Boolean128;
break;
1234 case dwarf::DW_ATE_complex_float:
1236 case 2: STK = SimpleTypeKind::Complex16;
break;
1237 case 4: STK = SimpleTypeKind::Complex32;
break;
1238 case 8: STK = SimpleTypeKind::Complex64;
break;
1239 case 10: STK = SimpleTypeKind::Complex80;
break;
1240 case 16: STK = SimpleTypeKind::Complex128;
break;
1243 case dwarf::DW_ATE_float:
1245 case 2: STK = SimpleTypeKind::Float16;
break;
1246 case 4: STK = SimpleTypeKind::Float32;
break;
1247 case 6: STK = SimpleTypeKind::Float48;
break;
1248 case 8: STK = SimpleTypeKind::Float64;
break;
1249 case 10: STK = SimpleTypeKind::Float80;
break;
1250 case 16: STK = SimpleTypeKind::Float128;
break;
1253 case dwarf::DW_ATE_signed:
1255 case 1: STK = SimpleTypeKind::SignedCharacter;
break;
1256 case 2: STK = SimpleTypeKind::Int16Short;
break;
1258 case 8: STK = SimpleTypeKind::Int64Quad;
break;
1259 case 16: STK = SimpleTypeKind::Int128Oct;
break;
1262 case dwarf::DW_ATE_unsigned:
1264 case 1: STK = SimpleTypeKind::UnsignedCharacter;
break;
1265 case 2: STK = SimpleTypeKind::UInt16Short;
break;
1267 case 8: STK = SimpleTypeKind::UInt64Quad;
break;
1268 case 16: STK = SimpleTypeKind::UInt128Oct;
break;
1271 case dwarf::DW_ATE_UTF:
1273 case 2: STK = SimpleTypeKind::Character16;
break;
1274 case 4: STK = SimpleTypeKind::Character32;
break;
1277 case dwarf::DW_ATE_signed_char:
1279 STK = SimpleTypeKind::SignedCharacter;
1281 case dwarf::DW_ATE_unsigned_char:
1283 STK = SimpleTypeKind::UnsignedCharacter;
1291 STK = SimpleTypeKind::Int32Long;
1293 STK = SimpleTypeKind::UInt32Long;
1294 if (STK == SimpleTypeKind::UInt16Short &&
1296 STK = SimpleTypeKind::WideCharacter;
1297 if ((STK == SimpleTypeKind::SignedCharacter ||
1298 STK == SimpleTypeKind::UnsignedCharacter) &&
1300 STK = SimpleTypeKind::NarrowCharacter;
1306 TypeIndex PointeeTI = getTypeIndex(Ty->getBaseType());
1312 Ty->
getTag() == dwarf::DW_TAG_pointer_type) {
1314 ? SimpleTypeMode::NearPointer64
1315 : SimpleTypeMode::NearPointer32;
1320 Ty->
getSizeInBits() == 64 ? PointerKind::Near64 : PointerKind::Near32;
1324 case dwarf::DW_TAG_pointer_type:
1325 PM = PointerMode::Pointer;
1327 case dwarf::DW_TAG_reference_type:
1328 PM = PointerMode::LValueReference;
1330 case dwarf::DW_TAG_rvalue_reference_type:
1331 PM = PointerMode::RValueReference;
1351 : PointerToMemberRepresentation::GeneralFunction;
1352 case DINode::FlagSingleInheritance:
1353 return PointerToMemberRepresentation::SingleInheritanceFunction;
1354 case DINode::FlagMultipleInheritance:
1355 return PointerToMemberRepresentation::MultipleInheritanceFunction;
1356 case DINode::FlagVirtualInheritance:
1357 return PointerToMemberRepresentation::VirtualInheritanceFunction;
1363 : PointerToMemberRepresentation::GeneralData;
1364 case DINode::FlagSingleInheritance:
1365 return PointerToMemberRepresentation::SingleInheritanceData;
1366 case DINode::FlagMultipleInheritance:
1367 return PointerToMemberRepresentation::MultipleInheritanceData;
1368 case DINode::FlagVirtualInheritance:
1369 return PointerToMemberRepresentation::VirtualInheritanceData;
1376 assert(Ty->
getTag() == dwarf::DW_TAG_ptr_to_member_type);
1377 TypeIndex ClassTI = getTypeIndex(Ty->getClassType());
1378 TypeIndex PointeeTI = getTypeIndex(Ty->getBaseType(), Ty->getClassType());
1380 : PointerKind::Near32;
1381 bool IsPMF = isa<DISubroutineType>(Ty->getBaseType());
1382 PointerMode PM = IsPMF ? PointerMode::PointerToMemberFunction
1383 : PointerMode::PointerToDataMember;
1397 case dwarf::DW_CC_normal:
return CallingConvention::NearC;
1398 case dwarf::DW_CC_BORLAND_msfastcall:
return CallingConvention::NearFast;
1399 case dwarf::DW_CC_BORLAND_thiscall:
return CallingConvention::ThisCall;
1400 case dwarf::DW_CC_BORLAND_stdcall:
return CallingConvention::NearStdCall;
1401 case dwarf::DW_CC_BORLAND_pascal:
return CallingConvention::NearPascal;
1402 case dwarf::DW_CC_LLVM_vectorcall:
return CallingConvention::NearVector;
1404 return CallingConvention::NearC;
1409 bool IsModifier =
true;
1410 const DIType *BaseTy = Ty;
1411 while (IsModifier && BaseTy) {
1413 switch (BaseTy->
getTag()) {
1414 case dwarf::DW_TAG_const_type:
1415 Mods |= ModifierOptions::Const;
1417 case dwarf::DW_TAG_volatile_type:
1418 Mods |= ModifierOptions::Volatile;
1425 BaseTy = cast<DIDerivedType>(BaseTy)->getBaseType().resolve();
1427 TypeIndex ModifiedTI = getTypeIndex(BaseTy);
1435 ReturnAndArgTypeIndices.
push_back(getTypeIndex(ArgTypeRef));
1437 TypeIndex ReturnTypeIndex = TypeIndex::Void();
1439 if (!ReturnAndArgTypeIndices.
empty()) {
1440 auto ReturnAndArgTypesRef =
makeArrayRef(ReturnAndArgTypeIndices);
1441 ReturnTypeIndex = ReturnAndArgTypesRef.front();
1442 ArgTypeIndices = ReturnAndArgTypesRef.
drop_front();
1445 ArgListRecord ArgListRec(TypeRecordKind::ArgList, ArgTypeIndices);
1451 ArgTypeIndices.
size(), ArgListIndex);
1457 int ThisAdjustment) {
1459 TypeIndex ClassType = getTypeIndex(ClassTy);
1463 ReturnAndArgTypeIndices.
push_back(getTypeIndex(ArgTypeRef));
1465 TypeIndex ReturnTypeIndex = TypeIndex::Void();
1467 if (!ReturnAndArgTypeIndices.
empty()) {
1468 auto ReturnAndArgTypesRef =
makeArrayRef(ReturnAndArgTypeIndices);
1469 ReturnTypeIndex = ReturnAndArgTypesRef.front();
1470 ArgTypeIndices = ReturnAndArgTypesRef.
drop_front();
1472 TypeIndex ThisTypeIndex = TypeIndex::Void();
1473 if (!ArgTypeIndices.
empty()) {
1474 ThisTypeIndex = ArgTypeIndices.
front();
1475 ArgTypeIndices = ArgTypeIndices.
drop_front();
1478 ArgListRecord ArgListRec(TypeRecordKind::ArgList, ArgTypeIndices);
1488 ArgListIndex, ThisAdjustment);
1505 case DINode::FlagPublic:
return MemberAccess::Public;
1506 case DINode::FlagProtected:
return MemberAccess::Protected;
1510 : MemberAccess::Public;
1516 if (SP->isArtificial())
1517 return MethodOptions::CompilerGenerated;
1526 switch (SP->getVirtuality()) {
1527 case dwarf::DW_VIRTUALITY_none:
1529 case dwarf::DW_VIRTUALITY_virtual:
1530 return Introduced ? MethodKind::IntroducingVirtual : MethodKind::Virtual;
1531 case dwarf::DW_VIRTUALITY_pure_virtual:
1532 return Introduced ? MethodKind::PureIntroducingVirtual
1533 : MethodKind::PureVirtual;
1540 return MethodKind::Vanilla;
1560 CO |= ClassOptions::HasUniqueName;
1566 if (ImmediateScope && isa<DICompositeType>(ImmediateScope))
1567 CO |= ClassOptions::Nested;
1570 for (
const DIScope *Scope = ImmediateScope; Scope !=
nullptr;
1571 Scope = Scope->getScope().resolve()) {
1572 if (isa<DISubprogram>(Scope)) {
1573 CO |= ClassOptions::Scoped;
1584 unsigned EnumeratorCount = 0;
1587 CO |= ClassOptions::ForwardReference;
1595 if (
auto *
Enumerator = dyn_cast_or_null<DIEnumerator>(Element)) {
1599 FLRB.writeMemberType(ER);
1642 void CodeViewDebug::clear() {
1643 assert(CurFn ==
nullptr);
1645 FnDebugInfo.clear();
1646 FileToFilepathMap.clear();
1649 TypeIndices.clear();
1650 CompleteTypeIndices.clear();
1653 void CodeViewDebug::collectMemberInfo(
ClassInfo &Info,
1656 Info.
Members.push_back({DDTy, 0});
1663 const DIType *Ty = DDTy->getBaseType().resolve();
1665 ClassInfo NestedInfo = collectClassInfo(DCTy);
1675 for (
auto *Element : Elements) {
1680 if (
auto *SP = dyn_cast<DISubprogram>(Element)) {
1681 Info.
Methods[SP->getRawName()].push_back(SP);
1682 }
else if (
auto *DDTy = dyn_cast<DIDerivedType>(Element)) {
1683 if (DDTy->
getTag() == dwarf::DW_TAG_member) {
1684 collectMemberInfo(Info, DDTy);
1685 }
else if (DDTy->
getTag() == dwarf::DW_TAG_inheritance) {
1687 }
else if (DDTy->
getTag() == dwarf::DW_TAG_pointer_type &&
1688 DDTy->
getName() ==
"__vtbl_ptr_type") {
1689 Info.
VShapeTI = getTypeIndex(DDTy);
1690 }
else if (DDTy->
getTag() == dwarf::DW_TAG_friend) {
1694 }
else if (
auto *Composite = dyn_cast<DICompositeType>(Element)) {
1713 DeferredCompleteTypes.push_back(Ty);
1723 unsigned FieldCount;
1725 std::tie(FieldTI, VShapeTI, FieldCount, ContainsNestedClass) =
1726 lowerRecordFieldList(Ty);
1728 if (ContainsNestedClass)
1729 CO |= ClassOptions::ContainsNestedClass;
1744 addToUDTs(Ty, ClassTI);
1756 DeferredCompleteTypes.push_back(Ty);
1763 unsigned FieldCount;
1764 bool ContainsNestedClass;
1765 std::tie(FieldTI, std::ignore, FieldCount, ContainsNestedClass) =
1766 lowerRecordFieldList(Ty);
1768 if (ContainsNestedClass)
1769 CO |= ClassOptions::ContainsNestedClass;
1774 UnionRecord UR(FieldCount, CO, FieldTI, SizeInBytes, FullName,
1783 addToUDTs(Ty, UnionTI);
1788 std::tuple<TypeIndex, TypeIndex, unsigned, bool>
1794 unsigned MemberCount = 0;
1801 if (I->
getFlags() & DINode::FlagVirtual) {
1804 unsigned VBPtrOffset = 0;
1807 auto RecordKind = (I->
getFlags() & DINode::FlagIndirectVirtualBase) == DINode::FlagIndirectVirtualBase
1808 ? TypeRecordKind::IndirectVirtualBaseClass
1809 : TypeRecordKind::VirtualBaseClass;
1812 getTypeIndex(I->getBaseType()), getVBPTypeIndex(), VBPtrOffset,
1815 FLBR.writeMemberType(VBCR);
1818 "bases must be on byte boundaries");
1820 getTypeIndex(I->getBaseType()),
1822 FLBR.writeMemberType(BCR);
1829 TypeIndex MemberBaseType = getTypeIndex(Member->getBaseType());
1836 FLBR.writeMemberType(SDMR);
1842 if ((Member->
getFlags() & DINode::FlagArtificial) &&
1844 VFPtrRecord VFPR(getTypeIndex(Member->getBaseType()));
1845 FLBR.writeMemberType(VFPR);
1851 uint64_t MemberOffsetInBits =
1854 uint64_t StartBitOffset = MemberOffsetInBits;
1855 if (
const auto *CI =
1856 dyn_cast_or_null<ConstantInt>(Member->getStorageOffsetInBits())) {
1857 MemberOffsetInBits = CI->getZExtValue() + MemberInfo.
BaseOffset;
1859 StartBitOffset -= MemberOffsetInBits;
1864 uint64_t MemberOffsetInBytes = MemberOffsetInBits / 8;
1867 FLBR.writeMemberType(DMR);
1872 for (
auto &MethodItr : Info.
Methods) {
1873 StringRef Name = MethodItr.first->getString();
1875 std::vector<OneMethodRecord> Methods;
1877 TypeIndex MethodType = getMemberFunctionType(SP, Ty);
1878 bool Introduced = SP->getFlags() & DINode::FlagIntroducedVirtual;
1880 unsigned VFTableOffset = -1;
1882 VFTableOffset = SP->getVirtualIndex() * getPointerSizeInBytes();
1890 assert(Methods.size() > 0 &&
"Empty methods map entry");
1891 if (Methods.size() == 1)
1892 FLBR.writeMemberType(Methods[0]);
1897 FLBR.writeMemberType(OMR);
1904 FLBR.writeMemberType(R);
1909 return std::make_tuple(FieldTI, Info.
VShapeTI, MemberCount,
1913 TypeIndex CodeViewDebug::getVBPTypeIndex() {
1919 PointerKind PK = getPointerSizeInBytes() == 8 ? PointerKind::Near64
1920 : PointerKind::Near32;
1923 PointerRecord PR(ModifiedTI, PK, PM, PO, getPointerSizeInBytes());
1937 return TypeIndex::Void();
1942 auto I = TypeIndices.find({Ty, ClassTy});
1943 if (I != TypeIndices.end())
1946 TypeLoweringScope S(*
this);
1948 return recordTypeIndexForDINode(Ty, TI, ClassTy);
1956 return TypeIndex::Void();
1961 case dwarf::DW_TAG_class_type:
1962 case dwarf::DW_TAG_structure_type:
1963 case dwarf::DW_TAG_union_type:
1966 return getTypeIndex(Ty);
1972 const auto *CTy = cast<DICompositeType>(Ty);
1973 auto InsertResult = CompleteTypeIndices.insert({CTy,
TypeIndex()});
1974 if (!InsertResult.second)
1975 return InsertResult.first->second;
1977 TypeLoweringScope S(*
this);
1982 TypeIndex FwdDeclTI = getTypeIndex(CTy);
1987 if (CTy->isForwardDecl())
1991 switch (CTy->getTag()) {
1992 case dwarf::DW_TAG_class_type:
1993 case dwarf::DW_TAG_structure_type:
1994 TI = lowerCompleteTypeClass(CTy);
1996 case dwarf::DW_TAG_union_type:
1997 TI = lowerCompleteTypeUnion(CTy);
2003 InsertResult.first->second = TI;
2011 void CodeViewDebug::emitDeferredCompleteTypes() {
2013 while (!DeferredCompleteTypes.empty()) {
2014 std::swap(DeferredCompleteTypes, TypesToEmit);
2016 getCompleteTypeIndex(RecordTy);
2017 TypesToEmit.clear();
2024 for (
const LocalVariable &
L : Locals)
2025 if (
L.DIVar->isParameter())
2027 std::sort(Params.
begin(), Params.
end(),
2028 [](
const LocalVariable *
L,
const LocalVariable *R) {
2029 return L->DIVar->getArg() < R->DIVar->getArg();
2031 for (
const LocalVariable *L : Params)
2032 emitLocalVariable(*L);
2035 for (
const LocalVariable &L : Locals)
2036 if (!L.DIVar->isParameter())
2037 emitLocalVariable(L);
2040 void CodeViewDebug::emitLocalVariable(
const LocalVariable &Var) {
2052 if (Var.DIVar->isParameter())
2053 Flags |= LocalSymFlags::IsParameter;
2054 if (Var.DefRanges.empty())
2055 Flags |= LocalSymFlags::IsOptimizedOut;
2058 TypeIndex TI = getCompleteTypeIndex(Var.DIVar->getType());
2070 for (
const LocalVarDefRange &DefRange : Var.DefRanges) {
2072 if (DefRange.InMemory) {
2073 uint16_t RegRelFlags = 0;
2074 if (DefRange.IsSubfield) {
2075 RegRelFlags = DefRangeRegisterRelSym::IsSubfieldFlag |
2076 (DefRange.StructOffset
2077 << DefRangeRegisterRelSym::OffsetInParentShift);
2080 Sym.Hdr.Register = DefRange.CVRegister;
2081 Sym.Hdr.Flags = RegRelFlags;
2082 Sym.Hdr.BasePointerOffset = DefRange.DataOffset;
2085 StringRef(reinterpret_cast<const char *>(&SymKind),
sizeof(SymKind));
2087 StringRef(reinterpret_cast<const char *>(&Sym.Hdr),
sizeof(Sym.Hdr));
2089 assert(DefRange.DataOffset == 0 &&
"unexpected offset into register");
2090 if (DefRange.IsSubfield) {
2093 Sym.Hdr.Register = DefRange.CVRegister;
2094 Sym.Hdr.MayHaveNoName = 0;
2095 Sym.Hdr.OffsetInParent = DefRange.StructOffset;
2098 BytePrefix +=
StringRef(reinterpret_cast<const char *>(&SymKind),
2100 BytePrefix +=
StringRef(reinterpret_cast<const char *>(&Sym.Hdr),
2105 Sym.Hdr.Register = DefRange.CVRegister;
2106 Sym.Hdr.MayHaveNoName = 0;
2108 BytePrefix +=
StringRef(reinterpret_cast<const char *>(&SymKind),
2110 BytePrefix +=
StringRef(reinterpret_cast<const char *>(&Sym.Hdr),
2123 assert(FnDebugInfo.count(GV));
2124 assert(CurFn == &FnDebugInfo[GV]);
2126 collectVariableInfo(GV->getSubprogram());
2131 if (!CurFn->HaveLineInfo) {
2132 FnDebugInfo.erase(GV);
2152 maybeRecordLocation(DL,
Asm->
MF);
2165 void CodeViewDebug::endCVSubsection(
MCSymbol *EndLabel) {
2171 void CodeViewDebug::emitDebugInfoForUDTs(
2172 ArrayRef<std::pair<std::string, TypeIndex>> UDTs) {
2173 for (
const std::pair<std::string, codeview::TypeIndex> &UDT : UDTs) {
2191 void CodeViewDebug::emitDebugInfoForGlobals() {
2196 GV.getDebugInfo(GVEs);
2197 for (
const auto *GVE : GVEs)
2198 GlobalMap[GVE] = &GV;
2203 const auto *CU = cast<DICompileUnit>(Node);
2208 switchToDebugSectionForSymbol(
nullptr);
2210 for (
const auto *GVE : CU->getGlobalVariables()) {
2211 if (
const auto *GV = GlobalMap.
lookup(GVE))
2214 OS.
AddComment(
"Symbol subsection for globals");
2215 EndLabel = beginCVSubsection(ModuleSubstreamKind::Symbols);
2218 emitDebugInfoForGlobal(GVE->getVariable(), GV,
Asm->
getSymbol(GV));
2222 endCVSubsection(EndLabel);
2226 for (
const auto *GVE : CU->getGlobalVariables()) {
2227 if (
const auto *GV = GlobalMap.
lookup(GVE)) {
2232 switchToDebugSectionForSymbol(GVSym);
2233 EndLabel = beginCVSubsection(ModuleSubstreamKind::Symbols);
2235 emitDebugInfoForGlobal(GVE->getVariable(), GV, GVSym);
2236 endCVSubsection(EndLabel);
2243 void CodeViewDebug::emitDebugInfoForRetainedTypes() {
2246 for (
auto *Ty : cast<DICompileUnit>(Node)->getRetainedTypes()) {
2247 if (
DIType *RT = dyn_cast<DIType>(Ty)) {
StringRef getName() const
Dumper for CodeView type streams found in COFF object files and PDB files.
PointerKind
Equivalent to CV_ptrtype_e.
TypeLoweringScope(CodeViewDebug &CVD)
void push_back(const T &Elt)
raw_ostream & errs()
This returns a reference to a raw_ostream for standard error.
virtual void EmitCVStringTableDirective()
This implements the CodeView '.cv_stringtable' assembler directive.
TypeIndex writeKnownType(T &Record)
StringRef getIdentifier() const
MCSymbol * getSymbol(const GlobalValue *GV) const
LLVM_ATTRIBUTE_NORETURN void report_fatal_error(Error Err, bool gen_crash_diag=true)
Report a serious error, calling any installed error handler.
ValueT lookup(const KeyT &Val) const
lookup - Return the entry for the specified key, or a default constructed value if no such entry exis...
MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...
virtual void AddBlankLine()
AddBlankLine - Emit a blank line to a .s file to pretty it up.
void logAllUnhandledErrors(Error E, raw_ostream &OS, Twine ErrorBanner)
Log all errors (if any) in E to OS.
const T & front() const
front - Get the first element.
CodeViewDebug(AsmPrinter *Asm)
DILocalScope * getScope() const
Get the local scope for this variable.
Implements a dense probed hash-table based set.
virtual void EmitBytes(StringRef Data)
Emit the bytes in Data into the output.
void endModule() override
Emit the COFF section that holds the line table information.
const MachineFunction * MF
The current machine function.
SmallVectorImpl< InsnRange > & getRanges()
A raw_ostream that writes to an SmallVector or SmallString.
DITypeRef getBaseType() const
const Function * getFunction() const
getFunction - Return the LLVM function that this machine code represents
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...
DebugLoc getFnDebugLoc() const
Find the debug info location for the start of the function.
const std::string & getTargetTriple() const
Get the target triple which is a string describing the target host.
VariableDbgInfoMapTy & getVariableDbgInfo()
Tagged DWARF-like metadata node.
StringRef getName() const
Return a constant reference to the value's name.
MCSectionCOFF * getAssociativeCOFFSection(MCSectionCOFF *Sec, const MCSymbol *KeySym, unsigned UniqueID=GenericSectionID)
Gets or creates a section equivalent to Sec that is associated with the section containing KeySym...
StringRef getCommentString() const
This represents a section on Windows.
DebugLoc PrevInstLoc
Previous instruction's location information.
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
struct fuzzer::@269 Flags
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
DILocation * get() const
Get the underlying DILocation.
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.
bool isImm() const
isImm - Tests if this is a MO_Immediate operand.
bool isReg() const
isReg - Tests if this is a MO_Register operand.
DINodeArray getElements() const
const Module * getModule() const
Reg
All possible values of the reg field in the ModR/M byte.
static StringRef getName(Value *V)
void beginFunction(const MachineFunction *MF) override
Gather pre-function debug information.
StringRef getFilename() const
static std::string getFullyQualifiedName(const DIScope *Scope, StringRef Name)
Error visitTypeStream(const CVTypeArray &Types)
Visits the type records in Data. Sets the error flag on parse failures.
Holds a subclass of DINode.
virtual bool isVerboseAsm() const
Return true if this streamer supports verbose assembly and if it is enabled.
bool hasDebugInfo() const
Returns true if valid debug info is present.
StringRef getName() const
MCContext & getContext() const
DITypeRefArray getTypeArray() const
virtual void EmitCVLocDirective(unsigned FunctionId, unsigned FileNo, unsigned Line, unsigned Column, bool PrologueEnd, bool IsStmt, StringRef FileName, SMLoc Loc)
This implements the CodeView '.cv_loc' assembler directive.
LLVM_NODISCARD bool empty() const
static StringRef getPrettyScopeName(const DIScope *Scope)
Context object for machine code objects.
auto reverse(ContainerTy &&C, typename std::enable_if< has_rbegin< ContainerTy >::value >::type *=nullptr) -> decltype(make_range(C.rbegin(), C.rend()))
virtual void AddComment(const Twine &T, bool EOL=true)
Add a textual comment.
virtual void EmitCVFileChecksumsDirective()
This implements the CodeView '.cv_filechecksums' assembler directive.
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.
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE bool startswith(StringRef Prefix) const
Check if this string starts with the given Prefix.
ModifierOptions
Equivalent to CV_modifier_t.
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory)...
static Optional< FragmentInfo > getFragmentInfo(expr_op_iterator Start, expr_op_iterator End)
Retrieve the details of this fragment expression.
DIScopeRef getScope() const
static GCRegistry::Add< OcamlGC > B("ocaml","ocaml 3.10-compatible GC")
virtual void emitRawComment(const Twine &T, bool TabPrefix=true)
Print T and prefix it with the comment string (normally #) and optionally a tab.
LexicalScope * findLexicalScope(const DILocation *DL)
findLexicalScope - Find lexical scope, either regular or inlined, for the given DebugLoc.
virtual void EmitBinaryData(StringRef Data)
Functionally identical to EmitBytes.
MethodKind
Part of member attribute flags. (CV_methodprop_e)
int getCodeViewRegNum(unsigned RegNum) const
Map a target register to an equivalent CodeView register number.
virtual void EmitIntValue(uint64_t Value, unsigned Size)
Special case of EmitValue that avoids the client having to pass in a MCExpr for constant integers...
iterator_range< op_iterator > operands()
DIScopeRef getScope() const
size_t size() const
size - Get the array size.
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...
uint32_t getIndex() const
static GCRegistry::Add< CoreCLRGC > E("coreclr","CoreCLR-compatible GC")
bool isDebugValue() const
TypeRecordKind
Distinguishes individual records in .debug$T section or PDB type stream.
std::vector< const DICompositeType * > NestedClasses
void beginInstruction(const MachineInstr *MI) override
Process beginning of an instruction.
void beginFunction(const MachineFunction *MF) override
Gather pre-function debug information.
Streaming machine code generation interface.
MCSymbol * createTempSymbol(bool CanBeUnnamed=true)
Create and return a new assembler temporary symbol with a unique but unspecified name.
static MemberAccess translateAccessFlags(unsigned RecordTag, unsigned Flags)
StringRef getName() const
static bool fragmentsOverlap(const DIExpression *P1, const DIExpression *P2)
Determine whether two variable fragments overlap.
const MCAsmInfo * MAI
Target Asm Printer information.
The instances of the Type class are immutable: once they are created, they are never changed...
virtual void EmitCVLinetableDirective(unsigned FunctionId, const MCSymbol *FnStart, const MCSymbol *FnEnd)
This implements the CodeView '.cv_linetable' assembler directive.
virtual void SwitchSection(MCSection *Section, const MCExpr *Subsection=nullptr)
Set the current section where code is being emitted to Section.
LLVM_ATTRIBUTE_ALWAYS_INLINE iterator begin()
This file contains the declarations for the subclasses of Constant, which represent the different fla...
const MachineOperand & getOperand(unsigned i) const
bool isLocalToUnit() const
AsmPrinter * Asm
Target of debug info emission.
MCSymbol * getCOMDATSymbol() const
std::pair< iterator, bool > insert(const ValueT &V)
This class is intended to be used as a driving class for all asm writers.
Greedy Register Allocator
virtual void EmitValueToAlignment(unsigned ByteAlignment, int64_t Value=0, unsigned ValueSize=1, unsigned MaxBytesToEmit=0)
Emit some number of copies of Value until the byte alignment ByteAlignment is reached.
For method overload sets. LF_METHOD.
static const unsigned End
bool getFlag(MIFlag Flag) const
Return whether an MI flag is set.
unsigned getEncoding() const
uint64_t getOffsetInBits() const
void beginInstruction(const MachineInstr *MI) override
Process beginning of an instruction.
bool empty() const
empty - Check if the array is empty.
void endFunction(const MachineFunction *MF) override
Gather post-function debug information.
SimpleTypeKind getSimpleKind() const
const DIExpression * getDebugExpression() const
Return the complex address expression referenced by this DBG_VALUE instruction.
bool isThreadLocal() const
If the value is "Thread Local", its value isn't shared by the threads.
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...
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
Triple - Helper class for working with autoconf configuration names.
DITypeRef getType() const
Base class for scope-like contexts.
LLVM_NODISCARD size_t rfind(char C, size_t From=npos) const
Search for the last character C in the string.
virtual bool EmitCVFileDirective(unsigned FileNo, StringRef Filename)
Associate a filename with a specified logical file number.
MCSection * getCOFFDebugTypesSection() const
unsigned getPointerSize() const
Get the pointer size in bytes.
PointerOptions
Equivalent to misc lfPointerAttr bitfields.
StringRef getDirectory() const
virtual const TargetFrameLowering * getFrameLowering() const
static void addLocIfNotPresent(SmallVectorImpl< const DILocation * > &Locs, const DILocation *Loc)
LexicalScope * findInlinedScope(const DILocalScope *N, const DILocation *IA)
findInlinedScope - Find an inlined scope for the given scope/inlined-at.
SourceLanguage
These values correspond to the CV_CFL_LANG enumeration, and are documented here: https://msdn.microsoft.com/en-us/library/bw3aekw6.aspx.
auto find(R &&Range, const T &Val) -> decltype(std::begin(Range))
Provide wrappers to std::find which take ranges instead of having to pass begin/end explicitly...
void setDebugInfoAvailability(bool avail)
static TypeRecordKind getRecordKind(const DICompositeType *Ty)
virtual void EmitLabel(MCSymbol *Symbol)
Emit a label for Symbol into the current section.
virtual void emitAbsoluteSymbolDiff(const MCSymbol *Hi, const MCSymbol *Lo, unsigned Size)
Emit the absolute difference between two symbols.
const MCContext & getContext() const
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small...
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.
static GCRegistry::Add< ShadowStackGC > C("shadow-stack","Very portable GC for uncooperative code generators")
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.
DISubprogram * getSubprogram() const
Get the attached subprogram.
bool isForwardDecl() const
bool isStaticMember() const
detail::packed_endian_specific_integral< uint16_t, little, unaligned > ulittle16_t
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE bool empty() const
empty - Check if the string is empty.
const DebugLoc & getDebugLoc() const
Returns the debug location id of this MachineInstr.
TinyPtrVector< const DISubprogram * > MethodsList
DebugLoc PrologEndLoc
This location indicates end of function prologue and beginning of function body.
void endFunction(const MachineFunction *) override
Gather post-function debug information.
MethodOptions
Equivalent to CV_fldattr_t bitfield.
MCSection & getSection(bool SetUsed=true) const
Get the section associated with a defined, non-absolute symbol.
static const DISubprogram * getQualifiedNameComponents(const DIScope *Scope, SmallVectorImpl< StringRef > &QualifiedNameComponents)
Dumper for CodeView type streams found in COFF object files and PDB files.
TargetSubtargetInfo - Generic base class for all target subtargets.
static MethodKind translateMethodKindFlags(const DISubprogram *SP, bool Introduced)
virtual void EmitCVDefRangeDirective(ArrayRef< std::pair< const MCSymbol *, const MCSymbol * >> Ranges, StringRef FixedSizePortion)
This implements the CodeView '.cv_def_range' assembler directive.
Type array for a subprogram.
Representation of each machine instruction.
const DIDerivedType * MemberTypeNode
static StringRef getRealLinkageName(StringRef Name)
If special LLVM prefix that is used to inform the asm printer to not emit usual symbol prefix before ...
const DataLayout & getDataLayout() const
Get the data layout for the module's target platform.
NamedMDNode * getNamedMetadata(const Twine &Name) const
Return the first NamedMDNode in the module with the specified name.
LLVM_ATTRIBUTE_ALWAYS_INLINE iterator end()
void emplace_back(ArgTypes &&...Args)
size_type count(const ValueT &V) const
Return 1 if the specified key is in the set, 0 otherwise.
void ForEachRecord(TFunc Func)
MCSymbol * getFunctionBegin() const
LLVM_ATTRIBUTE_ALWAYS_INLINE size_type size() const
unsigned getPointerSizeInBits(unsigned AS=0) const
Layout pointer size, in bits FIXME: The defaults need to be removed once all of the backends/clients ...
MCSymbol * getFunctionEnd() const
uint64_t getSizeInBits() const
MapVector< MDString *, MethodsList > MethodsMap
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.
std::pair< const MachineInstr *, const MachineInstr * > InsnRange
InsnRange - This is used to track range of instructions with identical lexical scope.
static void emitNullTerminatedSymbolName(MCStreamer &OS, StringRef S)
static std::string getQualifiedName(ArrayRef< StringRef > QualifiedNameComponents, StringRef TypeName)
PointerToMemberRepresentation
Equivalent to CV_pmtype_e.
bool hasLocalLinkage() const
MCSection * getCOFFDebugSymbolsSection() const
unsigned getReg() const
getReg - Returns the register number.
std::vector< MemberInfo > MemberList
MCSymbol * getLabelBeforeInsn(const MachineInstr *MI)
Return Label preceding the instruction.
MemberAccess
Source-level access specifier. (CV_access_e)
const TargetLoweringObjectFile & getObjFileLowering() const
Return information about object file lowering.
virtual void EmitCOFFSecRel32(MCSymbol const *Symbol, uint64_t Offset)
Emits a COFF section relative relocation.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
static APSInt getUnsigned(uint64_t X)
ArrayRef< T > drop_front(size_t N=1) const
Drop the first N elements of the array.
static MethodOptions translateMethodOptionFlags(const DISubprogram *SP)
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.
#define LLVM_FALLTHROUGH
LLVM_FALLTHROUGH - Mark fallthrough cases in switch statements.
virtual bool EmitCVFuncIdDirective(unsigned FunctionId)
Introduces a function id for use with .cv_loc.
Lightweight error class with error context and mandatory checking.
SimpleTypeMode getSimpleMode() const
CallingConvention
These values correspond to the CV_call_e enumeration, and are documented at the following locations: ...
MachineModuleInfo * MMI
Collected machine module information.
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.
virtual const TargetRegisterInfo * getRegisterInfo() const
getRegisterInfo - If register information is available, return it.
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.
Represents a location in source code.
LocalSymFlags
Corresponds to CV_LVARFLAGS bitfield.
TypedDINodeRef< DIType > DITypeRef
virtual void EmitCOFFSectionIndex(MCSymbol const *Symbol)
Emits a COFF section index.
bool isDeclarationForLinker() const
static ClassOptions getCommonClassOptions(const DICompositeType *Ty)
Return ClassOptions that should be present on both the forward declaration and the defintion of a tag...
MemberList Members
Direct members.
std::vector< const DIDerivedType * > Inheritance
Base classes.
Basic type, like 'int' or 'float'.