Path: blob/main/contrib/llvm-project/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp
35271 views
//===- llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp ----------------------===//1//2// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.3// See https://llvm.org/LICENSE.txt for license information.4// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception5//6//===----------------------------------------------------------------------===//7//8// This file contains support for writing Microsoft CodeView debug info.9//10//===----------------------------------------------------------------------===//1112#include "CodeViewDebug.h"13#include "llvm/ADT/APSInt.h"14#include "llvm/ADT/STLExtras.h"15#include "llvm/ADT/SmallBitVector.h"16#include "llvm/ADT/SmallString.h"17#include "llvm/ADT/StringRef.h"18#include "llvm/ADT/TinyPtrVector.h"19#include "llvm/ADT/Twine.h"20#include "llvm/BinaryFormat/COFF.h"21#include "llvm/BinaryFormat/Dwarf.h"22#include "llvm/CodeGen/AsmPrinter.h"23#include "llvm/CodeGen/LexicalScopes.h"24#include "llvm/CodeGen/MachineFrameInfo.h"25#include "llvm/CodeGen/MachineFunction.h"26#include "llvm/CodeGen/MachineInstr.h"27#include "llvm/CodeGen/MachineModuleInfo.h"28#include "llvm/CodeGen/TargetFrameLowering.h"29#include "llvm/CodeGen/TargetLowering.h"30#include "llvm/CodeGen/TargetRegisterInfo.h"31#include "llvm/CodeGen/TargetSubtargetInfo.h"32#include "llvm/Config/llvm-config.h"33#include "llvm/DebugInfo/CodeView/CVTypeVisitor.h"34#include "llvm/DebugInfo/CodeView/CodeViewRecordIO.h"35#include "llvm/DebugInfo/CodeView/ContinuationRecordBuilder.h"36#include "llvm/DebugInfo/CodeView/DebugInlineeLinesSubsection.h"37#include "llvm/DebugInfo/CodeView/EnumTables.h"38#include "llvm/DebugInfo/CodeView/Line.h"39#include "llvm/DebugInfo/CodeView/SymbolRecord.h"40#include "llvm/DebugInfo/CodeView/TypeRecord.h"41#include "llvm/DebugInfo/CodeView/TypeTableCollection.h"42#include "llvm/DebugInfo/CodeView/TypeVisitorCallbackPipeline.h"43#include "llvm/IR/Constants.h"44#include "llvm/IR/DataLayout.h"45#include "llvm/IR/DebugInfoMetadata.h"46#include "llvm/IR/Function.h"47#include "llvm/IR/GlobalValue.h"48#include "llvm/IR/GlobalVariable.h"49#include "llvm/IR/Metadata.h"50#include "llvm/IR/Module.h"51#include "llvm/MC/MCAsmInfo.h"52#include "llvm/MC/MCContext.h"53#include "llvm/MC/MCSectionCOFF.h"54#include "llvm/MC/MCStreamer.h"55#include "llvm/MC/MCSymbol.h"56#include "llvm/Support/BinaryStreamWriter.h"57#include "llvm/Support/Casting.h"58#include "llvm/Support/Error.h"59#include "llvm/Support/ErrorHandling.h"60#include "llvm/Support/FormatVariadic.h"61#include "llvm/Support/Path.h"62#include "llvm/Support/Program.h"63#include "llvm/Support/SMLoc.h"64#include "llvm/Support/ScopedPrinter.h"65#include "llvm/Target/TargetLoweringObjectFile.h"66#include "llvm/Target/TargetMachine.h"67#include "llvm/TargetParser/Triple.h"68#include <algorithm>69#include <cassert>70#include <cctype>71#include <cstddef>72#include <iterator>73#include <limits>7475using namespace llvm;76using namespace llvm::codeview;7778namespace {79class CVMCAdapter : public CodeViewRecordStreamer {80public:81CVMCAdapter(MCStreamer &OS, TypeCollection &TypeTable)82: OS(&OS), TypeTable(TypeTable) {}8384void emitBytes(StringRef Data) override { OS->emitBytes(Data); }8586void emitIntValue(uint64_t Value, unsigned Size) override {87OS->emitIntValueInHex(Value, Size);88}8990void emitBinaryData(StringRef Data) override { OS->emitBinaryData(Data); }9192void AddComment(const Twine &T) override { OS->AddComment(T); }9394void AddRawComment(const Twine &T) override { OS->emitRawComment(T); }9596bool isVerboseAsm() override { return OS->isVerboseAsm(); }9798std::string getTypeName(TypeIndex TI) override {99std::string TypeName;100if (!TI.isNoneType()) {101if (TI.isSimple())102TypeName = std::string(TypeIndex::simpleTypeName(TI));103else104TypeName = std::string(TypeTable.getTypeName(TI));105}106return TypeName;107}108109private:110MCStreamer *OS = nullptr;111TypeCollection &TypeTable;112};113} // namespace114115static CPUType mapArchToCVCPUType(Triple::ArchType Type) {116switch (Type) {117case Triple::ArchType::x86:118return CPUType::Pentium3;119case Triple::ArchType::x86_64:120return CPUType::X64;121case Triple::ArchType::thumb:122// LLVM currently doesn't support Windows CE and so thumb123// here is indiscriminately mapped to ARMNT specifically.124return CPUType::ARMNT;125case Triple::ArchType::aarch64:126return CPUType::ARM64;127default:128report_fatal_error("target architecture doesn't map to a CodeView CPUType");129}130}131132CodeViewDebug::CodeViewDebug(AsmPrinter *AP)133: DebugHandlerBase(AP), OS(*Asm->OutStreamer), TypeTable(Allocator) {}134135StringRef CodeViewDebug::getFullFilepath(const DIFile *File) {136std::string &Filepath = FileToFilepathMap[File];137if (!Filepath.empty())138return Filepath;139140StringRef Dir = File->getDirectory(), Filename = File->getFilename();141142// If this is a Unix-style path, just use it as is. Don't try to canonicalize143// it textually because one of the path components could be a symlink.144if (Dir.starts_with("/") || Filename.starts_with("/")) {145if (llvm::sys::path::is_absolute(Filename, llvm::sys::path::Style::posix))146return Filename;147Filepath = std::string(Dir);148if (Dir.back() != '/')149Filepath += '/';150Filepath += Filename;151return Filepath;152}153154// Clang emits directory and relative filename info into the IR, but CodeView155// operates on full paths. We could change Clang to emit full paths too, but156// that would increase the IR size and probably not needed for other users.157// For now, just concatenate and canonicalize the path here.158if (Filename.find(':') == 1)159Filepath = std::string(Filename);160else161Filepath = (Dir + "\\" + Filename).str();162163// Canonicalize the path. We have to do it textually because we may no longer164// have access the file in the filesystem.165// First, replace all slashes with backslashes.166std::replace(Filepath.begin(), Filepath.end(), '/', '\\');167168// Remove all "\.\" with "\".169size_t Cursor = 0;170while ((Cursor = Filepath.find("\\.\\", Cursor)) != std::string::npos)171Filepath.erase(Cursor, 2);172173// Replace all "\XXX\..\" with "\". Don't try too hard though as the original174// path should be well-formatted, e.g. start with a drive letter, etc.175Cursor = 0;176while ((Cursor = Filepath.find("\\..\\", Cursor)) != std::string::npos) {177// Something's wrong if the path starts with "\..\", abort.178if (Cursor == 0)179break;180181size_t PrevSlash = Filepath.rfind('\\', Cursor - 1);182if (PrevSlash == std::string::npos)183// Something's wrong, abort.184break;185186Filepath.erase(PrevSlash, Cursor + 3 - PrevSlash);187// The next ".." might be following the one we've just erased.188Cursor = PrevSlash;189}190191// Remove all duplicate backslashes.192Cursor = 0;193while ((Cursor = Filepath.find("\\\\", Cursor)) != std::string::npos)194Filepath.erase(Cursor, 1);195196return Filepath;197}198199unsigned CodeViewDebug::maybeRecordFile(const DIFile *F) {200StringRef FullPath = getFullFilepath(F);201unsigned NextId = FileIdMap.size() + 1;202auto Insertion = FileIdMap.insert(std::make_pair(FullPath, NextId));203if (Insertion.second) {204// We have to compute the full filepath and emit a .cv_file directive.205ArrayRef<uint8_t> ChecksumAsBytes;206FileChecksumKind CSKind = FileChecksumKind::None;207if (F->getChecksum()) {208std::string Checksum = fromHex(F->getChecksum()->Value);209void *CKMem = OS.getContext().allocate(Checksum.size(), 1);210memcpy(CKMem, Checksum.data(), Checksum.size());211ChecksumAsBytes = ArrayRef<uint8_t>(212reinterpret_cast<const uint8_t *>(CKMem), Checksum.size());213switch (F->getChecksum()->Kind) {214case DIFile::CSK_MD5:215CSKind = FileChecksumKind::MD5;216break;217case DIFile::CSK_SHA1:218CSKind = FileChecksumKind::SHA1;219break;220case DIFile::CSK_SHA256:221CSKind = FileChecksumKind::SHA256;222break;223}224}225bool Success = OS.emitCVFileDirective(NextId, FullPath, ChecksumAsBytes,226static_cast<unsigned>(CSKind));227(void)Success;228assert(Success && ".cv_file directive failed");229}230return Insertion.first->second;231}232233CodeViewDebug::InlineSite &234CodeViewDebug::getInlineSite(const DILocation *InlinedAt,235const DISubprogram *Inlinee) {236auto SiteInsertion = CurFn->InlineSites.insert({InlinedAt, InlineSite()});237InlineSite *Site = &SiteInsertion.first->second;238if (SiteInsertion.second) {239unsigned ParentFuncId = CurFn->FuncId;240if (const DILocation *OuterIA = InlinedAt->getInlinedAt())241ParentFuncId =242getInlineSite(OuterIA, InlinedAt->getScope()->getSubprogram())243.SiteFuncId;244245Site->SiteFuncId = NextFuncId++;246OS.emitCVInlineSiteIdDirective(247Site->SiteFuncId, ParentFuncId, maybeRecordFile(InlinedAt->getFile()),248InlinedAt->getLine(), InlinedAt->getColumn(), SMLoc());249Site->Inlinee = Inlinee;250InlinedSubprograms.insert(Inlinee);251auto InlineeIdx = getFuncIdForSubprogram(Inlinee);252253if (InlinedAt->getInlinedAt() == nullptr)254CurFn->Inlinees.insert(InlineeIdx);255}256return *Site;257}258259static StringRef getPrettyScopeName(const DIScope *Scope) {260StringRef ScopeName = Scope->getName();261if (!ScopeName.empty())262return ScopeName;263264switch (Scope->getTag()) {265case dwarf::DW_TAG_enumeration_type:266case dwarf::DW_TAG_class_type:267case dwarf::DW_TAG_structure_type:268case dwarf::DW_TAG_union_type:269return "<unnamed-tag>";270case dwarf::DW_TAG_namespace:271return "`anonymous namespace'";272default:273return StringRef();274}275}276277const DISubprogram *CodeViewDebug::collectParentScopeNames(278const DIScope *Scope, SmallVectorImpl<StringRef> &QualifiedNameComponents) {279const DISubprogram *ClosestSubprogram = nullptr;280while (Scope != nullptr) {281if (ClosestSubprogram == nullptr)282ClosestSubprogram = dyn_cast<DISubprogram>(Scope);283284// If a type appears in a scope chain, make sure it gets emitted. The285// frontend will be responsible for deciding if this should be a forward286// declaration or a complete type.287if (const auto *Ty = dyn_cast<DICompositeType>(Scope))288DeferredCompleteTypes.push_back(Ty);289290StringRef ScopeName = getPrettyScopeName(Scope);291if (!ScopeName.empty())292QualifiedNameComponents.push_back(ScopeName);293Scope = Scope->getScope();294}295return ClosestSubprogram;296}297298static std::string formatNestedName(ArrayRef<StringRef> QualifiedNameComponents,299StringRef TypeName) {300std::string FullyQualifiedName;301for (StringRef QualifiedNameComponent :302llvm::reverse(QualifiedNameComponents)) {303FullyQualifiedName.append(std::string(QualifiedNameComponent));304FullyQualifiedName.append("::");305}306FullyQualifiedName.append(std::string(TypeName));307return FullyQualifiedName;308}309310struct CodeViewDebug::TypeLoweringScope {311TypeLoweringScope(CodeViewDebug &CVD) : CVD(CVD) { ++CVD.TypeEmissionLevel; }312~TypeLoweringScope() {313// Don't decrement TypeEmissionLevel until after emitting deferred types, so314// inner TypeLoweringScopes don't attempt to emit deferred types.315if (CVD.TypeEmissionLevel == 1)316CVD.emitDeferredCompleteTypes();317--CVD.TypeEmissionLevel;318}319CodeViewDebug &CVD;320};321322std::string CodeViewDebug::getFullyQualifiedName(const DIScope *Scope,323StringRef Name) {324// Ensure types in the scope chain are emitted as soon as possible.325// This can create otherwise a situation where S_UDTs are emitted while326// looping in emitDebugInfoForUDTs.327TypeLoweringScope S(*this);328SmallVector<StringRef, 5> QualifiedNameComponents;329collectParentScopeNames(Scope, QualifiedNameComponents);330return formatNestedName(QualifiedNameComponents, Name);331}332333std::string CodeViewDebug::getFullyQualifiedName(const DIScope *Ty) {334const DIScope *Scope = Ty->getScope();335return getFullyQualifiedName(Scope, getPrettyScopeName(Ty));336}337338TypeIndex CodeViewDebug::getScopeIndex(const DIScope *Scope) {339// No scope means global scope and that uses the zero index.340//341// We also use zero index when the scope is a DISubprogram342// to suppress the emission of LF_STRING_ID for the function,343// which can trigger a link-time error with the linker in344// VS2019 version 16.11.2 or newer.345// Note, however, skipping the debug info emission for the DISubprogram346// is a temporary fix. The root issue here is that we need to figure out347// the proper way to encode a function nested in another function348// (as introduced by the Fortran 'contains' keyword) in CodeView.349if (!Scope || isa<DIFile>(Scope) || isa<DISubprogram>(Scope))350return TypeIndex();351352assert(!isa<DIType>(Scope) && "shouldn't make a namespace scope for a type");353354// Check if we've already translated this scope.355auto I = TypeIndices.find({Scope, nullptr});356if (I != TypeIndices.end())357return I->second;358359// Build the fully qualified name of the scope.360std::string ScopeName = getFullyQualifiedName(Scope);361StringIdRecord SID(TypeIndex(), ScopeName);362auto TI = TypeTable.writeLeafType(SID);363return recordTypeIndexForDINode(Scope, TI);364}365366static StringRef removeTemplateArgs(StringRef Name) {367// Remove template args from the display name. Assume that the template args368// are the last thing in the name.369if (Name.empty() || Name.back() != '>')370return Name;371372int OpenBrackets = 0;373for (int i = Name.size() - 1; i >= 0; --i) {374if (Name[i] == '>')375++OpenBrackets;376else if (Name[i] == '<') {377--OpenBrackets;378if (OpenBrackets == 0)379return Name.substr(0, i);380}381}382return Name;383}384385TypeIndex CodeViewDebug::getFuncIdForSubprogram(const DISubprogram *SP) {386assert(SP);387388// Check if we've already translated this subprogram.389auto I = TypeIndices.find({SP, nullptr});390if (I != TypeIndices.end())391return I->second;392393// The display name includes function template arguments. Drop them to match394// MSVC. We need to have the template arguments in the DISubprogram name395// because they are used in other symbol records, such as S_GPROC32_IDs.396StringRef DisplayName = removeTemplateArgs(SP->getName());397398const DIScope *Scope = SP->getScope();399TypeIndex TI;400if (const auto *Class = dyn_cast_or_null<DICompositeType>(Scope)) {401// If the scope is a DICompositeType, then this must be a method. Member402// function types take some special handling, and require access to the403// subprogram.404TypeIndex ClassType = getTypeIndex(Class);405MemberFuncIdRecord MFuncId(ClassType, getMemberFunctionType(SP, Class),406DisplayName);407TI = TypeTable.writeLeafType(MFuncId);408} else {409// Otherwise, this must be a free function.410TypeIndex ParentScope = getScopeIndex(Scope);411FuncIdRecord FuncId(ParentScope, getTypeIndex(SP->getType()), DisplayName);412TI = TypeTable.writeLeafType(FuncId);413}414415return recordTypeIndexForDINode(SP, TI);416}417418static bool isNonTrivial(const DICompositeType *DCTy) {419return ((DCTy->getFlags() & DINode::FlagNonTrivial) == DINode::FlagNonTrivial);420}421422static FunctionOptions423getFunctionOptions(const DISubroutineType *Ty,424const DICompositeType *ClassTy = nullptr,425StringRef SPName = StringRef("")) {426FunctionOptions FO = FunctionOptions::None;427const DIType *ReturnTy = nullptr;428if (auto TypeArray = Ty->getTypeArray()) {429if (TypeArray.size())430ReturnTy = TypeArray[0];431}432433// Add CxxReturnUdt option to functions that return nontrivial record types434// or methods that return record types.435if (auto *ReturnDCTy = dyn_cast_or_null<DICompositeType>(ReturnTy))436if (isNonTrivial(ReturnDCTy) || ClassTy)437FO |= FunctionOptions::CxxReturnUdt;438439// DISubroutineType is unnamed. Use DISubprogram's i.e. SPName in comparison.440if (ClassTy && isNonTrivial(ClassTy) && SPName == ClassTy->getName()) {441FO |= FunctionOptions::Constructor;442443// TODO: put the FunctionOptions::ConstructorWithVirtualBases flag.444445}446return FO;447}448449TypeIndex CodeViewDebug::getMemberFunctionType(const DISubprogram *SP,450const DICompositeType *Class) {451// Always use the method declaration as the key for the function type. The452// method declaration contains the this adjustment.453if (SP->getDeclaration())454SP = SP->getDeclaration();455assert(!SP->getDeclaration() && "should use declaration as key");456457// Key the MemberFunctionRecord into the map as {SP, Class}. It won't collide458// with the MemberFuncIdRecord, which is keyed in as {SP, nullptr}.459auto I = TypeIndices.find({SP, Class});460if (I != TypeIndices.end())461return I->second;462463// Make sure complete type info for the class is emitted *after* the member464// function type, as the complete class type is likely to reference this465// member function type.466TypeLoweringScope S(*this);467const bool IsStaticMethod = (SP->getFlags() & DINode::FlagStaticMember) != 0;468469FunctionOptions FO = getFunctionOptions(SP->getType(), Class, SP->getName());470TypeIndex TI = lowerTypeMemberFunction(471SP->getType(), Class, SP->getThisAdjustment(), IsStaticMethod, FO);472return recordTypeIndexForDINode(SP, TI, Class);473}474475TypeIndex CodeViewDebug::recordTypeIndexForDINode(const DINode *Node,476TypeIndex TI,477const DIType *ClassTy) {478auto InsertResult = TypeIndices.insert({{Node, ClassTy}, TI});479(void)InsertResult;480assert(InsertResult.second && "DINode was already assigned a type index");481return TI;482}483484unsigned CodeViewDebug::getPointerSizeInBytes() {485return MMI->getModule()->getDataLayout().getPointerSizeInBits() / 8;486}487488void CodeViewDebug::recordLocalVariable(LocalVariable &&Var,489const LexicalScope *LS) {490if (const DILocation *InlinedAt = LS->getInlinedAt()) {491// This variable was inlined. Associate it with the InlineSite.492const DISubprogram *Inlinee = Var.DIVar->getScope()->getSubprogram();493InlineSite &Site = getInlineSite(InlinedAt, Inlinee);494Site.InlinedLocals.emplace_back(std::move(Var));495} else {496// This variable goes into the corresponding lexical scope.497ScopeVariables[LS].emplace_back(std::move(Var));498}499}500501static void addLocIfNotPresent(SmallVectorImpl<const DILocation *> &Locs,502const DILocation *Loc) {503if (!llvm::is_contained(Locs, Loc))504Locs.push_back(Loc);505}506507void CodeViewDebug::maybeRecordLocation(const DebugLoc &DL,508const MachineFunction *MF) {509// Skip this instruction if it has the same location as the previous one.510if (!DL || DL == PrevInstLoc)511return;512513const DIScope *Scope = DL->getScope();514if (!Scope)515return;516517// Skip this line if it is longer than the maximum we can record.518LineInfo LI(DL.getLine(), DL.getLine(), /*IsStatement=*/true);519if (LI.getStartLine() != DL.getLine() || LI.isAlwaysStepInto() ||520LI.isNeverStepInto())521return;522523ColumnInfo CI(DL.getCol(), /*EndColumn=*/0);524if (CI.getStartColumn() != DL.getCol())525return;526527if (!CurFn->HaveLineInfo)528CurFn->HaveLineInfo = true;529unsigned FileId = 0;530if (PrevInstLoc.get() && PrevInstLoc->getFile() == DL->getFile())531FileId = CurFn->LastFileId;532else533FileId = CurFn->LastFileId = maybeRecordFile(DL->getFile());534PrevInstLoc = DL;535536unsigned FuncId = CurFn->FuncId;537if (const DILocation *SiteLoc = DL->getInlinedAt()) {538const DILocation *Loc = DL.get();539540// If this location was actually inlined from somewhere else, give it the ID541// of the inline call site.542FuncId =543getInlineSite(SiteLoc, Loc->getScope()->getSubprogram()).SiteFuncId;544545// Ensure we have links in the tree of inline call sites.546bool FirstLoc = true;547while ((SiteLoc = Loc->getInlinedAt())) {548InlineSite &Site =549getInlineSite(SiteLoc, Loc->getScope()->getSubprogram());550if (!FirstLoc)551addLocIfNotPresent(Site.ChildSites, Loc);552FirstLoc = false;553Loc = SiteLoc;554}555addLocIfNotPresent(CurFn->ChildSites, Loc);556}557558OS.emitCVLocDirective(FuncId, FileId, DL.getLine(), DL.getCol(),559/*PrologueEnd=*/false, /*IsStmt=*/false,560DL->getFilename(), SMLoc());561}562563void CodeViewDebug::emitCodeViewMagicVersion() {564OS.emitValueToAlignment(Align(4));565OS.AddComment("Debug section magic");566OS.emitInt32(COFF::DEBUG_SECTION_MAGIC);567}568569static SourceLanguage MapDWLangToCVLang(unsigned DWLang) {570switch (DWLang) {571case dwarf::DW_LANG_C:572case dwarf::DW_LANG_C89:573case dwarf::DW_LANG_C99:574case dwarf::DW_LANG_C11:575return SourceLanguage::C;576case dwarf::DW_LANG_C_plus_plus:577case dwarf::DW_LANG_C_plus_plus_03:578case dwarf::DW_LANG_C_plus_plus_11:579case dwarf::DW_LANG_C_plus_plus_14:580return SourceLanguage::Cpp;581case dwarf::DW_LANG_Fortran77:582case dwarf::DW_LANG_Fortran90:583case dwarf::DW_LANG_Fortran95:584case dwarf::DW_LANG_Fortran03:585case dwarf::DW_LANG_Fortran08:586return SourceLanguage::Fortran;587case dwarf::DW_LANG_Pascal83:588return SourceLanguage::Pascal;589case dwarf::DW_LANG_Cobol74:590case dwarf::DW_LANG_Cobol85:591return SourceLanguage::Cobol;592case dwarf::DW_LANG_Java:593return SourceLanguage::Java;594case dwarf::DW_LANG_D:595return SourceLanguage::D;596case dwarf::DW_LANG_Swift:597return SourceLanguage::Swift;598case dwarf::DW_LANG_Rust:599return SourceLanguage::Rust;600case dwarf::DW_LANG_ObjC:601return SourceLanguage::ObjC;602case dwarf::DW_LANG_ObjC_plus_plus:603return SourceLanguage::ObjCpp;604default:605// There's no CodeView representation for this language, and CV doesn't606// have an "unknown" option for the language field, so we'll use MASM,607// as it's very low level.608return SourceLanguage::Masm;609}610}611612void CodeViewDebug::beginModule(Module *M) {613// If module doesn't have named metadata anchors or COFF debug section614// is not available, skip any debug info related stuff.615if (!MMI->hasDebugInfo() ||616!Asm->getObjFileLowering().getCOFFDebugSymbolsSection()) {617Asm = nullptr;618return;619}620621TheCPU = mapArchToCVCPUType(Triple(M->getTargetTriple()).getArch());622623// Get the current source language.624const MDNode *Node = *M->debug_compile_units_begin();625const auto *CU = cast<DICompileUnit>(Node);626627CurrentSourceLanguage = MapDWLangToCVLang(CU->getSourceLanguage());628629collectGlobalVariableInfo();630631// Check if we should emit type record hashes.632ConstantInt *GH =633mdconst::extract_or_null<ConstantInt>(M->getModuleFlag("CodeViewGHash"));634EmitDebugGlobalHashes = GH && !GH->isZero();635}636637void CodeViewDebug::endModule() {638if (!Asm || !MMI->hasDebugInfo())639return;640641// The COFF .debug$S section consists of several subsections, each starting642// with a 4-byte control code (e.g. 0xF1, 0xF2, etc) and then a 4-byte length643// of the payload followed by the payload itself. The subsections are 4-byte644// aligned.645646// Use the generic .debug$S section, and make a subsection for all the inlined647// subprograms.648switchToDebugSectionForSymbol(nullptr);649650MCSymbol *CompilerInfo = beginCVSubsection(DebugSubsectionKind::Symbols);651emitObjName();652emitCompilerInformation();653endCVSubsection(CompilerInfo);654655emitInlineeLinesSubsection();656657// Emit per-function debug information.658for (auto &P : FnDebugInfo)659if (!P.first->isDeclarationForLinker())660emitDebugInfoForFunction(P.first, *P.second);661662// Get types used by globals without emitting anything.663// This is meant to collect all static const data members so they can be664// emitted as globals.665collectDebugInfoForGlobals();666667// Emit retained types.668emitDebugInfoForRetainedTypes();669670// Emit global variable debug information.671setCurrentSubprogram(nullptr);672emitDebugInfoForGlobals();673674// Switch back to the generic .debug$S section after potentially processing675// comdat symbol sections.676switchToDebugSectionForSymbol(nullptr);677678// Emit UDT records for any types used by global variables.679if (!GlobalUDTs.empty()) {680MCSymbol *SymbolsEnd = beginCVSubsection(DebugSubsectionKind::Symbols);681emitDebugInfoForUDTs(GlobalUDTs);682endCVSubsection(SymbolsEnd);683}684685// This subsection holds a file index to offset in string table table.686OS.AddComment("File index to string table offset subsection");687OS.emitCVFileChecksumsDirective();688689// This subsection holds the string table.690OS.AddComment("String table");691OS.emitCVStringTableDirective();692693// Emit S_BUILDINFO, which points to LF_BUILDINFO. Put this in its own symbol694// subsection in the generic .debug$S section at the end. There is no695// particular reason for this ordering other than to match MSVC.696emitBuildInfo();697698// Emit type information and hashes last, so that any types we translate while699// emitting function info are included.700emitTypeInformation();701702if (EmitDebugGlobalHashes)703emitTypeGlobalHashes();704705clear();706}707708static void709emitNullTerminatedSymbolName(MCStreamer &OS, StringRef S,710unsigned MaxFixedRecordLength = 0xF00) {711// The maximum CV record length is 0xFF00. Most of the strings we emit appear712// after a fixed length portion of the record. The fixed length portion should713// always be less than 0xF00 (3840) bytes, so truncate the string so that the714// overall record size is less than the maximum allowed.715SmallString<32> NullTerminatedString(716S.take_front(MaxRecordLength - MaxFixedRecordLength - 1));717NullTerminatedString.push_back('\0');718OS.emitBytes(NullTerminatedString);719}720721void CodeViewDebug::emitTypeInformation() {722if (TypeTable.empty())723return;724725// Start the .debug$T or .debug$P section with 0x4.726OS.switchSection(Asm->getObjFileLowering().getCOFFDebugTypesSection());727emitCodeViewMagicVersion();728729TypeTableCollection Table(TypeTable.records());730TypeVisitorCallbackPipeline Pipeline;731732// To emit type record using Codeview MCStreamer adapter733CVMCAdapter CVMCOS(OS, Table);734TypeRecordMapping typeMapping(CVMCOS);735Pipeline.addCallbackToPipeline(typeMapping);736737std::optional<TypeIndex> B = Table.getFirst();738while (B) {739// This will fail if the record data is invalid.740CVType Record = Table.getType(*B);741742Error E = codeview::visitTypeRecord(Record, *B, Pipeline);743744if (E) {745logAllUnhandledErrors(std::move(E), errs(), "error: ");746llvm_unreachable("produced malformed type record");747}748749B = Table.getNext(*B);750}751}752753void CodeViewDebug::emitTypeGlobalHashes() {754if (TypeTable.empty())755return;756757// Start the .debug$H section with the version and hash algorithm, currently758// hardcoded to version 0, SHA1.759OS.switchSection(Asm->getObjFileLowering().getCOFFGlobalTypeHashesSection());760761OS.emitValueToAlignment(Align(4));762OS.AddComment("Magic");763OS.emitInt32(COFF::DEBUG_HASHES_SECTION_MAGIC);764OS.AddComment("Section Version");765OS.emitInt16(0);766OS.AddComment("Hash Algorithm");767OS.emitInt16(uint16_t(GlobalTypeHashAlg::BLAKE3));768769TypeIndex TI(TypeIndex::FirstNonSimpleIndex);770for (const auto &GHR : TypeTable.hashes()) {771if (OS.isVerboseAsm()) {772// Emit an EOL-comment describing which TypeIndex this hash corresponds773// to, as well as the stringified SHA1 hash.774SmallString<32> Comment;775raw_svector_ostream CommentOS(Comment);776CommentOS << formatv("{0:X+} [{1}]", TI.getIndex(), GHR);777OS.AddComment(Comment);778++TI;779}780assert(GHR.Hash.size() == 8);781StringRef S(reinterpret_cast<const char *>(GHR.Hash.data()),782GHR.Hash.size());783OS.emitBinaryData(S);784}785}786787void CodeViewDebug::emitObjName() {788MCSymbol *CompilerEnd = beginSymbolRecord(SymbolKind::S_OBJNAME);789790StringRef PathRef(Asm->TM.Options.ObjectFilenameForDebug);791llvm::SmallString<256> PathStore(PathRef);792793if (PathRef.empty() || PathRef == "-") {794// Don't emit the filename if we're writing to stdout or to /dev/null.795PathRef = {};796} else {797PathRef = PathStore;798}799800OS.AddComment("Signature");801OS.emitIntValue(0, 4);802803OS.AddComment("Object name");804emitNullTerminatedSymbolName(OS, PathRef);805806endSymbolRecord(CompilerEnd);807}808809namespace {810struct Version {811int Part[4];812};813} // end anonymous namespace814815// Takes a StringRef like "clang 4.0.0.0 (other nonsense 123)" and parses out816// the version number.817static Version parseVersion(StringRef Name) {818Version V = {{0}};819int N = 0;820for (const char C : Name) {821if (isdigit(C)) {822V.Part[N] *= 10;823V.Part[N] += C - '0';824V.Part[N] =825std::min<int>(V.Part[N], std::numeric_limits<uint16_t>::max());826} else if (C == '.') {827++N;828if (N >= 4)829return V;830} else if (N > 0)831return V;832}833return V;834}835836void CodeViewDebug::emitCompilerInformation() {837MCSymbol *CompilerEnd = beginSymbolRecord(SymbolKind::S_COMPILE3);838uint32_t Flags = 0;839840// The low byte of the flags indicates the source language.841Flags = CurrentSourceLanguage;842// TODO: Figure out which other flags need to be set.843if (MMI->getModule()->getProfileSummary(/*IsCS*/ false) != nullptr) {844Flags |= static_cast<uint32_t>(CompileSym3Flags::PGO);845}846using ArchType = llvm::Triple::ArchType;847ArchType Arch = Triple(MMI->getModule()->getTargetTriple()).getArch();848if (Asm->TM.Options.Hotpatch || Arch == ArchType::thumb ||849Arch == ArchType::aarch64) {850Flags |= static_cast<uint32_t>(CompileSym3Flags::HotPatch);851}852853OS.AddComment("Flags and language");854OS.emitInt32(Flags);855856OS.AddComment("CPUType");857OS.emitInt16(static_cast<uint64_t>(TheCPU));858859NamedMDNode *CUs = MMI->getModule()->getNamedMetadata("llvm.dbg.cu");860const MDNode *Node = *CUs->operands().begin();861const auto *CU = cast<DICompileUnit>(Node);862863StringRef CompilerVersion = CU->getProducer();864Version FrontVer = parseVersion(CompilerVersion);865OS.AddComment("Frontend version");866for (int N : FrontVer.Part) {867OS.emitInt16(N);868}869870// Some Microsoft tools, like Binscope, expect a backend version number of at871// least 8.something, so we'll coerce the LLVM version into a form that872// guarantees it'll be big enough without really lying about the version.873int Major = 1000 * LLVM_VERSION_MAJOR +87410 * LLVM_VERSION_MINOR +875LLVM_VERSION_PATCH;876// Clamp it for builds that use unusually large version numbers.877Major = std::min<int>(Major, std::numeric_limits<uint16_t>::max());878Version BackVer = {{ Major, 0, 0, 0 }};879OS.AddComment("Backend version");880for (int N : BackVer.Part)881OS.emitInt16(N);882883OS.AddComment("Null-terminated compiler version string");884emitNullTerminatedSymbolName(OS, CompilerVersion);885886endSymbolRecord(CompilerEnd);887}888889static TypeIndex getStringIdTypeIdx(GlobalTypeTableBuilder &TypeTable,890StringRef S) {891StringIdRecord SIR(TypeIndex(0x0), S);892return TypeTable.writeLeafType(SIR);893}894895static std::string flattenCommandLine(ArrayRef<std::string> Args,896StringRef MainFilename) {897std::string FlatCmdLine;898raw_string_ostream OS(FlatCmdLine);899bool PrintedOneArg = false;900if (!StringRef(Args[0]).contains("-cc1")) {901llvm::sys::printArg(OS, "-cc1", /*Quote=*/true);902PrintedOneArg = true;903}904for (unsigned i = 0; i < Args.size(); i++) {905StringRef Arg = Args[i];906if (Arg.empty())907continue;908if (Arg == "-main-file-name" || Arg == "-o") {909i++; // Skip this argument and next one.910continue;911}912if (Arg.starts_with("-object-file-name") || Arg == MainFilename)913continue;914// Skip fmessage-length for reproduciability.915if (Arg.starts_with("-fmessage-length"))916continue;917if (PrintedOneArg)918OS << " ";919llvm::sys::printArg(OS, Arg, /*Quote=*/true);920PrintedOneArg = true;921}922OS.flush();923return FlatCmdLine;924}925926void CodeViewDebug::emitBuildInfo() {927// First, make LF_BUILDINFO. It's a sequence of strings with various bits of928// build info. The known prefix is:929// - Absolute path of current directory930// - Compiler path931// - Main source file path, relative to CWD or absolute932// - Type server PDB file933// - Canonical compiler command line934// If frontend and backend compilation are separated (think llc or LTO), it's935// not clear if the compiler path should refer to the executable for the936// frontend or the backend. Leave it blank for now.937TypeIndex BuildInfoArgs[BuildInfoRecord::MaxArgs] = {};938NamedMDNode *CUs = MMI->getModule()->getNamedMetadata("llvm.dbg.cu");939const MDNode *Node = *CUs->operands().begin(); // FIXME: Multiple CUs.940const auto *CU = cast<DICompileUnit>(Node);941const DIFile *MainSourceFile = CU->getFile();942BuildInfoArgs[BuildInfoRecord::CurrentDirectory] =943getStringIdTypeIdx(TypeTable, MainSourceFile->getDirectory());944BuildInfoArgs[BuildInfoRecord::SourceFile] =945getStringIdTypeIdx(TypeTable, MainSourceFile->getFilename());946// FIXME: PDB is intentionally blank unless we implement /Zi type servers.947BuildInfoArgs[BuildInfoRecord::TypeServerPDB] =948getStringIdTypeIdx(TypeTable, "");949if (Asm->TM.Options.MCOptions.Argv0 != nullptr) {950BuildInfoArgs[BuildInfoRecord::BuildTool] =951getStringIdTypeIdx(TypeTable, Asm->TM.Options.MCOptions.Argv0);952BuildInfoArgs[BuildInfoRecord::CommandLine] = getStringIdTypeIdx(953TypeTable, flattenCommandLine(Asm->TM.Options.MCOptions.CommandLineArgs,954MainSourceFile->getFilename()));955}956BuildInfoRecord BIR(BuildInfoArgs);957TypeIndex BuildInfoIndex = TypeTable.writeLeafType(BIR);958959// Make a new .debug$S subsection for the S_BUILDINFO record, which points960// from the module symbols into the type stream.961MCSymbol *BISubsecEnd = beginCVSubsection(DebugSubsectionKind::Symbols);962MCSymbol *BIEnd = beginSymbolRecord(SymbolKind::S_BUILDINFO);963OS.AddComment("LF_BUILDINFO index");964OS.emitInt32(BuildInfoIndex.getIndex());965endSymbolRecord(BIEnd);966endCVSubsection(BISubsecEnd);967}968969void CodeViewDebug::emitInlineeLinesSubsection() {970if (InlinedSubprograms.empty())971return;972973OS.AddComment("Inlinee lines subsection");974MCSymbol *InlineEnd = beginCVSubsection(DebugSubsectionKind::InlineeLines);975976// We emit the checksum info for files. This is used by debuggers to977// determine if a pdb matches the source before loading it. Visual Studio,978// for instance, will display a warning that the breakpoints are not valid if979// the pdb does not match the source.980OS.AddComment("Inlinee lines signature");981OS.emitInt32(unsigned(InlineeLinesSignature::Normal));982983for (const DISubprogram *SP : InlinedSubprograms) {984assert(TypeIndices.count({SP, nullptr}));985TypeIndex InlineeIdx = TypeIndices[{SP, nullptr}];986987OS.addBlankLine();988unsigned FileId = maybeRecordFile(SP->getFile());989OS.AddComment("Inlined function " + SP->getName() + " starts at " +990SP->getFilename() + Twine(':') + Twine(SP->getLine()));991OS.addBlankLine();992OS.AddComment("Type index of inlined function");993OS.emitInt32(InlineeIdx.getIndex());994OS.AddComment("Offset into filechecksum table");995OS.emitCVFileChecksumOffsetDirective(FileId);996OS.AddComment("Starting line number");997OS.emitInt32(SP->getLine());998}9991000endCVSubsection(InlineEnd);1001}10021003void CodeViewDebug::emitInlinedCallSite(const FunctionInfo &FI,1004const DILocation *InlinedAt,1005const InlineSite &Site) {1006assert(TypeIndices.count({Site.Inlinee, nullptr}));1007TypeIndex InlineeIdx = TypeIndices[{Site.Inlinee, nullptr}];10081009// SymbolRecord1010MCSymbol *InlineEnd = beginSymbolRecord(SymbolKind::S_INLINESITE);10111012OS.AddComment("PtrParent");1013OS.emitInt32(0);1014OS.AddComment("PtrEnd");1015OS.emitInt32(0);1016OS.AddComment("Inlinee type index");1017OS.emitInt32(InlineeIdx.getIndex());10181019unsigned FileId = maybeRecordFile(Site.Inlinee->getFile());1020unsigned StartLineNum = Site.Inlinee->getLine();10211022OS.emitCVInlineLinetableDirective(Site.SiteFuncId, FileId, StartLineNum,1023FI.Begin, FI.End);10241025endSymbolRecord(InlineEnd);10261027emitLocalVariableList(FI, Site.InlinedLocals);10281029// Recurse on child inlined call sites before closing the scope.1030for (const DILocation *ChildSite : Site.ChildSites) {1031auto I = FI.InlineSites.find(ChildSite);1032assert(I != FI.InlineSites.end() &&1033"child site not in function inline site map");1034emitInlinedCallSite(FI, ChildSite, I->second);1035}10361037// Close the scope.1038emitEndSymbolRecord(SymbolKind::S_INLINESITE_END);1039}10401041void CodeViewDebug::switchToDebugSectionForSymbol(const MCSymbol *GVSym) {1042// If we have a symbol, it may be in a section that is COMDAT. If so, find the1043// comdat key. A section may be comdat because of -ffunction-sections or1044// because it is comdat in the IR.1045MCSectionCOFF *GVSec =1046GVSym ? dyn_cast<MCSectionCOFF>(&GVSym->getSection()) : nullptr;1047const MCSymbol *KeySym = GVSec ? GVSec->getCOMDATSymbol() : nullptr;10481049MCSectionCOFF *DebugSec = cast<MCSectionCOFF>(1050Asm->getObjFileLowering().getCOFFDebugSymbolsSection());1051DebugSec = OS.getContext().getAssociativeCOFFSection(DebugSec, KeySym);10521053OS.switchSection(DebugSec);10541055// Emit the magic version number if this is the first time we've switched to1056// this section.1057if (ComdatDebugSections.insert(DebugSec).second)1058emitCodeViewMagicVersion();1059}10601061// Emit an S_THUNK32/S_END symbol pair for a thunk routine.1062// The only supported thunk ordinal is currently the standard type.1063void CodeViewDebug::emitDebugInfoForThunk(const Function *GV,1064FunctionInfo &FI,1065const MCSymbol *Fn) {1066std::string FuncName =1067std::string(GlobalValue::dropLLVMManglingEscape(GV->getName()));1068const ThunkOrdinal ordinal = ThunkOrdinal::Standard; // Only supported kind.10691070OS.AddComment("Symbol subsection for " + Twine(FuncName));1071MCSymbol *SymbolsEnd = beginCVSubsection(DebugSubsectionKind::Symbols);10721073// Emit S_THUNK321074MCSymbol *ThunkRecordEnd = beginSymbolRecord(SymbolKind::S_THUNK32);1075OS.AddComment("PtrParent");1076OS.emitInt32(0);1077OS.AddComment("PtrEnd");1078OS.emitInt32(0);1079OS.AddComment("PtrNext");1080OS.emitInt32(0);1081OS.AddComment("Thunk section relative address");1082OS.emitCOFFSecRel32(Fn, /*Offset=*/0);1083OS.AddComment("Thunk section index");1084OS.emitCOFFSectionIndex(Fn);1085OS.AddComment("Code size");1086OS.emitAbsoluteSymbolDiff(FI.End, Fn, 2);1087OS.AddComment("Ordinal");1088OS.emitInt8(unsigned(ordinal));1089OS.AddComment("Function name");1090emitNullTerminatedSymbolName(OS, FuncName);1091// Additional fields specific to the thunk ordinal would go here.1092endSymbolRecord(ThunkRecordEnd);10931094// Local variables/inlined routines are purposely omitted here. The point of1095// marking this as a thunk is so Visual Studio will NOT stop in this routine.10961097// Emit S_PROC_ID_END1098emitEndSymbolRecord(SymbolKind::S_PROC_ID_END);10991100endCVSubsection(SymbolsEnd);1101}11021103void CodeViewDebug::emitDebugInfoForFunction(const Function *GV,1104FunctionInfo &FI) {1105// For each function there is a separate subsection which holds the PC to1106// file:line table.1107const MCSymbol *Fn = Asm->getSymbol(GV);1108assert(Fn);11091110// Switch to the to a comdat section, if appropriate.1111switchToDebugSectionForSymbol(Fn);11121113std::string FuncName;1114auto *SP = GV->getSubprogram();1115assert(SP);1116setCurrentSubprogram(SP);11171118if (SP->isThunk()) {1119emitDebugInfoForThunk(GV, FI, Fn);1120return;1121}11221123// If we have a display name, build the fully qualified name by walking the1124// chain of scopes.1125if (!SP->getName().empty())1126FuncName = getFullyQualifiedName(SP->getScope(), SP->getName());11271128// If our DISubprogram name is empty, use the mangled name.1129if (FuncName.empty())1130FuncName = std::string(GlobalValue::dropLLVMManglingEscape(GV->getName()));11311132// Emit FPO data, but only on 32-bit x86. No other platforms use it.1133if (Triple(MMI->getModule()->getTargetTriple()).getArch() == Triple::x86)1134OS.emitCVFPOData(Fn);11351136// Emit a symbol subsection, required by VS2012+ to find function boundaries.1137OS.AddComment("Symbol subsection for " + Twine(FuncName));1138MCSymbol *SymbolsEnd = beginCVSubsection(DebugSubsectionKind::Symbols);1139{1140SymbolKind ProcKind = GV->hasLocalLinkage() ? SymbolKind::S_LPROC32_ID1141: SymbolKind::S_GPROC32_ID;1142MCSymbol *ProcRecordEnd = beginSymbolRecord(ProcKind);11431144// These fields are filled in by tools like CVPACK which run after the fact.1145OS.AddComment("PtrParent");1146OS.emitInt32(0);1147OS.AddComment("PtrEnd");1148OS.emitInt32(0);1149OS.AddComment("PtrNext");1150OS.emitInt32(0);1151// This is the important bit that tells the debugger where the function1152// code is located and what's its size:1153OS.AddComment("Code size");1154OS.emitAbsoluteSymbolDiff(FI.End, Fn, 4);1155OS.AddComment("Offset after prologue");1156OS.emitInt32(0);1157OS.AddComment("Offset before epilogue");1158OS.emitInt32(0);1159OS.AddComment("Function type index");1160OS.emitInt32(getFuncIdForSubprogram(GV->getSubprogram()).getIndex());1161OS.AddComment("Function section relative address");1162OS.emitCOFFSecRel32(Fn, /*Offset=*/0);1163OS.AddComment("Function section index");1164OS.emitCOFFSectionIndex(Fn);1165OS.AddComment("Flags");1166ProcSymFlags ProcFlags = ProcSymFlags::HasOptimizedDebugInfo;1167if (FI.HasFramePointer)1168ProcFlags |= ProcSymFlags::HasFP;1169if (GV->hasFnAttribute(Attribute::NoReturn))1170ProcFlags |= ProcSymFlags::IsNoReturn;1171if (GV->hasFnAttribute(Attribute::NoInline))1172ProcFlags |= ProcSymFlags::IsNoInline;1173OS.emitInt8(static_cast<uint8_t>(ProcFlags));1174// Emit the function display name as a null-terminated string.1175OS.AddComment("Function name");1176// Truncate the name so we won't overflow the record length field.1177emitNullTerminatedSymbolName(OS, FuncName);1178endSymbolRecord(ProcRecordEnd);11791180MCSymbol *FrameProcEnd = beginSymbolRecord(SymbolKind::S_FRAMEPROC);1181// Subtract out the CSR size since MSVC excludes that and we include it.1182OS.AddComment("FrameSize");1183OS.emitInt32(FI.FrameSize - FI.CSRSize);1184OS.AddComment("Padding");1185OS.emitInt32(0);1186OS.AddComment("Offset of padding");1187OS.emitInt32(0);1188OS.AddComment("Bytes of callee saved registers");1189OS.emitInt32(FI.CSRSize);1190OS.AddComment("Exception handler offset");1191OS.emitInt32(0);1192OS.AddComment("Exception handler section");1193OS.emitInt16(0);1194OS.AddComment("Flags (defines frame register)");1195OS.emitInt32(uint32_t(FI.FrameProcOpts));1196endSymbolRecord(FrameProcEnd);11971198emitInlinees(FI.Inlinees);1199emitLocalVariableList(FI, FI.Locals);1200emitGlobalVariableList(FI.Globals);1201emitLexicalBlockList(FI.ChildBlocks, FI);12021203// Emit inlined call site information. Only emit functions inlined directly1204// into the parent function. We'll emit the other sites recursively as part1205// of their parent inline site.1206for (const DILocation *InlinedAt : FI.ChildSites) {1207auto I = FI.InlineSites.find(InlinedAt);1208assert(I != FI.InlineSites.end() &&1209"child site not in function inline site map");1210emitInlinedCallSite(FI, InlinedAt, I->second);1211}12121213for (auto Annot : FI.Annotations) {1214MCSymbol *Label = Annot.first;1215MDTuple *Strs = cast<MDTuple>(Annot.second);1216MCSymbol *AnnotEnd = beginSymbolRecord(SymbolKind::S_ANNOTATION);1217OS.emitCOFFSecRel32(Label, /*Offset=*/0);1218// FIXME: Make sure we don't overflow the max record size.1219OS.emitCOFFSectionIndex(Label);1220OS.emitInt16(Strs->getNumOperands());1221for (Metadata *MD : Strs->operands()) {1222// MDStrings are null terminated, so we can do EmitBytes and get the1223// nice .asciz directive.1224StringRef Str = cast<MDString>(MD)->getString();1225assert(Str.data()[Str.size()] == '\0' && "non-nullterminated MDString");1226OS.emitBytes(StringRef(Str.data(), Str.size() + 1));1227}1228endSymbolRecord(AnnotEnd);1229}12301231for (auto HeapAllocSite : FI.HeapAllocSites) {1232const MCSymbol *BeginLabel = std::get<0>(HeapAllocSite);1233const MCSymbol *EndLabel = std::get<1>(HeapAllocSite);1234const DIType *DITy = std::get<2>(HeapAllocSite);1235MCSymbol *HeapAllocEnd = beginSymbolRecord(SymbolKind::S_HEAPALLOCSITE);1236OS.AddComment("Call site offset");1237OS.emitCOFFSecRel32(BeginLabel, /*Offset=*/0);1238OS.AddComment("Call site section index");1239OS.emitCOFFSectionIndex(BeginLabel);1240OS.AddComment("Call instruction length");1241OS.emitAbsoluteSymbolDiff(EndLabel, BeginLabel, 2);1242OS.AddComment("Type index");1243OS.emitInt32(getCompleteTypeIndex(DITy).getIndex());1244endSymbolRecord(HeapAllocEnd);1245}12461247if (SP != nullptr)1248emitDebugInfoForUDTs(LocalUDTs);12491250emitDebugInfoForJumpTables(FI);12511252// We're done with this function.1253emitEndSymbolRecord(SymbolKind::S_PROC_ID_END);1254}1255endCVSubsection(SymbolsEnd);12561257// We have an assembler directive that takes care of the whole line table.1258OS.emitCVLinetableDirective(FI.FuncId, Fn, FI.End);1259}12601261CodeViewDebug::LocalVarDef1262CodeViewDebug::createDefRangeMem(uint16_t CVRegister, int Offset) {1263LocalVarDef DR;1264DR.InMemory = -1;1265DR.DataOffset = Offset;1266assert(DR.DataOffset == Offset && "truncation");1267DR.IsSubfield = 0;1268DR.StructOffset = 0;1269DR.CVRegister = CVRegister;1270return DR;1271}12721273void CodeViewDebug::collectVariableInfoFromMFTable(1274DenseSet<InlinedEntity> &Processed) {1275const MachineFunction &MF = *Asm->MF;1276const TargetSubtargetInfo &TSI = MF.getSubtarget();1277const TargetFrameLowering *TFI = TSI.getFrameLowering();1278const TargetRegisterInfo *TRI = TSI.getRegisterInfo();12791280for (const MachineFunction::VariableDbgInfo &VI :1281MF.getInStackSlotVariableDbgInfo()) {1282if (!VI.Var)1283continue;1284assert(VI.Var->isValidLocationForIntrinsic(VI.Loc) &&1285"Expected inlined-at fields to agree");12861287Processed.insert(InlinedEntity(VI.Var, VI.Loc->getInlinedAt()));1288LexicalScope *Scope = LScopes.findLexicalScope(VI.Loc);12891290// If variable scope is not found then skip this variable.1291if (!Scope)1292continue;12931294// If the variable has an attached offset expression, extract it.1295// FIXME: Try to handle DW_OP_deref as well.1296int64_t ExprOffset = 0;1297bool Deref = false;1298if (VI.Expr) {1299// If there is one DW_OP_deref element, use offset of 0 and keep going.1300if (VI.Expr->getNumElements() == 1 &&1301VI.Expr->getElement(0) == llvm::dwarf::DW_OP_deref)1302Deref = true;1303else if (!VI.Expr->extractIfOffset(ExprOffset))1304continue;1305}13061307// Get the frame register used and the offset.1308Register FrameReg;1309StackOffset FrameOffset =1310TFI->getFrameIndexReference(*Asm->MF, VI.getStackSlot(), FrameReg);1311uint16_t CVReg = TRI->getCodeViewRegNum(FrameReg);13121313assert(!FrameOffset.getScalable() &&1314"Frame offsets with a scalable component are not supported");13151316// Calculate the label ranges.1317LocalVarDef DefRange =1318createDefRangeMem(CVReg, FrameOffset.getFixed() + ExprOffset);13191320LocalVariable Var;1321Var.DIVar = VI.Var;13221323for (const InsnRange &Range : Scope->getRanges()) {1324const MCSymbol *Begin = getLabelBeforeInsn(Range.first);1325const MCSymbol *End = getLabelAfterInsn(Range.second);1326End = End ? End : Asm->getFunctionEnd();1327Var.DefRanges[DefRange].emplace_back(Begin, End);1328}13291330if (Deref)1331Var.UseReferenceType = true;13321333recordLocalVariable(std::move(Var), Scope);1334}1335}13361337static bool canUseReferenceType(const DbgVariableLocation &Loc) {1338return !Loc.LoadChain.empty() && Loc.LoadChain.back() == 0;1339}13401341static bool needsReferenceType(const DbgVariableLocation &Loc) {1342return Loc.LoadChain.size() == 2 && Loc.LoadChain.back() == 0;1343}13441345void CodeViewDebug::calculateRanges(1346LocalVariable &Var, const DbgValueHistoryMap::Entries &Entries) {1347const TargetRegisterInfo *TRI = Asm->MF->getSubtarget().getRegisterInfo();13481349// Calculate the definition ranges.1350for (auto I = Entries.begin(), E = Entries.end(); I != E; ++I) {1351const auto &Entry = *I;1352if (!Entry.isDbgValue())1353continue;1354const MachineInstr *DVInst = Entry.getInstr();1355assert(DVInst->isDebugValue() && "Invalid History entry");1356// FIXME: Find a way to represent constant variables, since they are1357// relatively common.1358std::optional<DbgVariableLocation> Location =1359DbgVariableLocation::extractFromMachineInstruction(*DVInst);1360if (!Location)1361{1362// When we don't have a location this is usually because LLVM has1363// transformed it into a constant and we only have an llvm.dbg.value. We1364// can't represent these well in CodeView since S_LOCAL only works on1365// registers and memory locations. Instead, we will pretend this to be a1366// constant value to at least have it show up in the debugger.1367auto Op = DVInst->getDebugOperand(0);1368if (Op.isImm())1369Var.ConstantValue = APSInt(APInt(64, Op.getImm()), false);1370continue;1371}13721373// CodeView can only express variables in register and variables in memory1374// at a constant offset from a register. However, for variables passed1375// indirectly by pointer, it is common for that pointer to be spilled to a1376// stack location. For the special case of one offseted load followed by a1377// zero offset load (a pointer spilled to the stack), we change the type of1378// the local variable from a value type to a reference type. This tricks the1379// debugger into doing the load for us.1380if (Var.UseReferenceType) {1381// We're using a reference type. Drop the last zero offset load.1382if (canUseReferenceType(*Location))1383Location->LoadChain.pop_back();1384else1385continue;1386} else if (needsReferenceType(*Location)) {1387// This location can't be expressed without switching to a reference type.1388// Start over using that.1389Var.UseReferenceType = true;1390Var.DefRanges.clear();1391calculateRanges(Var, Entries);1392return;1393}13941395// We can only handle a register or an offseted load of a register.1396if (Location->Register == 0 || Location->LoadChain.size() > 1)1397continue;13981399// Codeview can only express byte-aligned offsets, ensure that we have a1400// byte-boundaried location.1401if (Location->FragmentInfo)1402if (Location->FragmentInfo->OffsetInBits % 8)1403continue;14041405LocalVarDef DR;1406DR.CVRegister = TRI->getCodeViewRegNum(Location->Register);1407DR.InMemory = !Location->LoadChain.empty();1408DR.DataOffset =1409!Location->LoadChain.empty() ? Location->LoadChain.back() : 0;1410if (Location->FragmentInfo) {1411DR.IsSubfield = true;1412DR.StructOffset = Location->FragmentInfo->OffsetInBits / 8;1413} else {1414DR.IsSubfield = false;1415DR.StructOffset = 0;1416}14171418// Compute the label range.1419const MCSymbol *Begin = getLabelBeforeInsn(Entry.getInstr());1420const MCSymbol *End;1421if (Entry.getEndIndex() != DbgValueHistoryMap::NoEntry) {1422auto &EndingEntry = Entries[Entry.getEndIndex()];1423End = EndingEntry.isDbgValue()1424? getLabelBeforeInsn(EndingEntry.getInstr())1425: getLabelAfterInsn(EndingEntry.getInstr());1426} else1427End = Asm->getFunctionEnd();14281429// If the last range end is our begin, just extend the last range.1430// Otherwise make a new range.1431SmallVectorImpl<std::pair<const MCSymbol *, const MCSymbol *>> &R =1432Var.DefRanges[DR];1433if (!R.empty() && R.back().second == Begin)1434R.back().second = End;1435else1436R.emplace_back(Begin, End);14371438// FIXME: Do more range combining.1439}1440}14411442void CodeViewDebug::collectVariableInfo(const DISubprogram *SP) {1443DenseSet<InlinedEntity> Processed;1444// Grab the variable info that was squirreled away in the MMI side-table.1445collectVariableInfoFromMFTable(Processed);14461447for (const auto &I : DbgValues) {1448InlinedEntity IV = I.first;1449if (Processed.count(IV))1450continue;1451const DILocalVariable *DIVar = cast<DILocalVariable>(IV.first);1452const DILocation *InlinedAt = IV.second;14531454// Instruction ranges, specifying where IV is accessible.1455const auto &Entries = I.second;14561457LexicalScope *Scope = nullptr;1458if (InlinedAt)1459Scope = LScopes.findInlinedScope(DIVar->getScope(), InlinedAt);1460else1461Scope = LScopes.findLexicalScope(DIVar->getScope());1462// If variable scope is not found then skip this variable.1463if (!Scope)1464continue;14651466LocalVariable Var;1467Var.DIVar = DIVar;14681469calculateRanges(Var, Entries);1470recordLocalVariable(std::move(Var), Scope);1471}1472}14731474void CodeViewDebug::beginFunctionImpl(const MachineFunction *MF) {1475const TargetSubtargetInfo &TSI = MF->getSubtarget();1476const TargetRegisterInfo *TRI = TSI.getRegisterInfo();1477const MachineFrameInfo &MFI = MF->getFrameInfo();1478const Function &GV = MF->getFunction();1479auto Insertion = FnDebugInfo.insert({&GV, std::make_unique<FunctionInfo>()});1480assert(Insertion.second && "function already has info");1481CurFn = Insertion.first->second.get();1482CurFn->FuncId = NextFuncId++;1483CurFn->Begin = Asm->getFunctionBegin();14841485// The S_FRAMEPROC record reports the stack size, and how many bytes of1486// callee-saved registers were used. For targets that don't use a PUSH1487// instruction (AArch64), this will be zero.1488CurFn->CSRSize = MFI.getCVBytesOfCalleeSavedRegisters();1489CurFn->FrameSize = MFI.getStackSize();1490CurFn->OffsetAdjustment = MFI.getOffsetAdjustment();1491CurFn->HasStackRealignment = TRI->hasStackRealignment(*MF);14921493// For this function S_FRAMEPROC record, figure out which codeview register1494// will be the frame pointer.1495CurFn->EncodedParamFramePtrReg = EncodedFramePtrReg::None; // None.1496CurFn->EncodedLocalFramePtrReg = EncodedFramePtrReg::None; // None.1497if (CurFn->FrameSize > 0) {1498if (!TSI.getFrameLowering()->hasFP(*MF)) {1499CurFn->EncodedLocalFramePtrReg = EncodedFramePtrReg::StackPtr;1500CurFn->EncodedParamFramePtrReg = EncodedFramePtrReg::StackPtr;1501} else {1502CurFn->HasFramePointer = true;1503// If there is an FP, parameters are always relative to it.1504CurFn->EncodedParamFramePtrReg = EncodedFramePtrReg::FramePtr;1505if (CurFn->HasStackRealignment) {1506// If the stack needs realignment, locals are relative to SP or VFRAME.1507CurFn->EncodedLocalFramePtrReg = EncodedFramePtrReg::StackPtr;1508} else {1509// Otherwise, locals are relative to EBP, and we probably have VLAs or1510// other stack adjustments.1511CurFn->EncodedLocalFramePtrReg = EncodedFramePtrReg::FramePtr;1512}1513}1514}15151516// Compute other frame procedure options.1517FrameProcedureOptions FPO = FrameProcedureOptions::None;1518if (MFI.hasVarSizedObjects())1519FPO |= FrameProcedureOptions::HasAlloca;1520if (MF->exposesReturnsTwice())1521FPO |= FrameProcedureOptions::HasSetJmp;1522// FIXME: Set HasLongJmp if we ever track that info.1523if (MF->hasInlineAsm())1524FPO |= FrameProcedureOptions::HasInlineAssembly;1525if (GV.hasPersonalityFn()) {1526if (isAsynchronousEHPersonality(1527classifyEHPersonality(GV.getPersonalityFn())))1528FPO |= FrameProcedureOptions::HasStructuredExceptionHandling;1529else1530FPO |= FrameProcedureOptions::HasExceptionHandling;1531}1532if (GV.hasFnAttribute(Attribute::InlineHint))1533FPO |= FrameProcedureOptions::MarkedInline;1534if (GV.hasFnAttribute(Attribute::Naked))1535FPO |= FrameProcedureOptions::Naked;1536if (MFI.hasStackProtectorIndex()) {1537FPO |= FrameProcedureOptions::SecurityChecks;1538if (GV.hasFnAttribute(Attribute::StackProtectStrong) ||1539GV.hasFnAttribute(Attribute::StackProtectReq)) {1540FPO |= FrameProcedureOptions::StrictSecurityChecks;1541}1542} else if (!GV.hasStackProtectorFnAttr()) {1543// __declspec(safebuffers) disables stack guards.1544FPO |= FrameProcedureOptions::SafeBuffers;1545}1546FPO |= FrameProcedureOptions(uint32_t(CurFn->EncodedLocalFramePtrReg) << 14U);1547FPO |= FrameProcedureOptions(uint32_t(CurFn->EncodedParamFramePtrReg) << 16U);1548if (Asm->TM.getOptLevel() != CodeGenOptLevel::None && !GV.hasOptSize() &&1549!GV.hasOptNone())1550FPO |= FrameProcedureOptions::OptimizedForSpeed;1551if (GV.hasProfileData()) {1552FPO |= FrameProcedureOptions::ValidProfileCounts;1553FPO |= FrameProcedureOptions::ProfileGuidedOptimization;1554}1555// FIXME: Set GuardCfg when it is implemented.1556CurFn->FrameProcOpts = FPO;15571558OS.emitCVFuncIdDirective(CurFn->FuncId);15591560// Find the end of the function prolog. First known non-DBG_VALUE and1561// non-frame setup location marks the beginning of the function body.1562// FIXME: is there a simpler a way to do this? Can we just search1563// for the first instruction of the function, not the last of the prolog?1564DebugLoc PrologEndLoc;1565bool EmptyPrologue = true;1566for (const auto &MBB : *MF) {1567for (const auto &MI : MBB) {1568if (!MI.isMetaInstruction() && !MI.getFlag(MachineInstr::FrameSetup) &&1569MI.getDebugLoc()) {1570PrologEndLoc = MI.getDebugLoc();1571break;1572} else if (!MI.isMetaInstruction()) {1573EmptyPrologue = false;1574}1575}1576}15771578// Record beginning of function if we have a non-empty prologue.1579if (PrologEndLoc && !EmptyPrologue) {1580DebugLoc FnStartDL = PrologEndLoc.getFnDebugLoc();1581maybeRecordLocation(FnStartDL, MF);1582}15831584// Find heap alloc sites and emit labels around them.1585for (const auto &MBB : *MF) {1586for (const auto &MI : MBB) {1587if (MI.getHeapAllocMarker()) {1588requestLabelBeforeInsn(&MI);1589requestLabelAfterInsn(&MI);1590}1591}1592}15931594// Mark branches that may potentially be using jump tables with labels.1595bool isThumb = Triple(MMI->getModule()->getTargetTriple()).getArch() ==1596llvm::Triple::ArchType::thumb;1597discoverJumpTableBranches(MF, isThumb);1598}15991600static bool shouldEmitUdt(const DIType *T) {1601if (!T)1602return false;16031604// MSVC does not emit UDTs for typedefs that are scoped to classes.1605if (T->getTag() == dwarf::DW_TAG_typedef) {1606if (DIScope *Scope = T->getScope()) {1607switch (Scope->getTag()) {1608case dwarf::DW_TAG_structure_type:1609case dwarf::DW_TAG_class_type:1610case dwarf::DW_TAG_union_type:1611return false;1612default:1613// do nothing.1614;1615}1616}1617}16181619while (true) {1620if (!T || T->isForwardDecl())1621return false;16221623const DIDerivedType *DT = dyn_cast<DIDerivedType>(T);1624if (!DT)1625return true;1626T = DT->getBaseType();1627}1628return true;1629}16301631void CodeViewDebug::addToUDTs(const DIType *Ty) {1632// Don't record empty UDTs.1633if (Ty->getName().empty())1634return;1635if (!shouldEmitUdt(Ty))1636return;16371638SmallVector<StringRef, 5> ParentScopeNames;1639const DISubprogram *ClosestSubprogram =1640collectParentScopeNames(Ty->getScope(), ParentScopeNames);16411642std::string FullyQualifiedName =1643formatNestedName(ParentScopeNames, getPrettyScopeName(Ty));16441645if (ClosestSubprogram == nullptr) {1646GlobalUDTs.emplace_back(std::move(FullyQualifiedName), Ty);1647} else if (ClosestSubprogram == CurrentSubprogram) {1648LocalUDTs.emplace_back(std::move(FullyQualifiedName), Ty);1649}16501651// TODO: What if the ClosestSubprogram is neither null or the current1652// subprogram? Currently, the UDT just gets dropped on the floor.1653//1654// The current behavior is not desirable. To get maximal fidelity, we would1655// need to perform all type translation before beginning emission of .debug$S1656// and then make LocalUDTs a member of FunctionInfo1657}16581659TypeIndex CodeViewDebug::lowerType(const DIType *Ty, const DIType *ClassTy) {1660// Generic dispatch for lowering an unknown type.1661switch (Ty->getTag()) {1662case dwarf::DW_TAG_array_type:1663return lowerTypeArray(cast<DICompositeType>(Ty));1664case dwarf::DW_TAG_typedef:1665return lowerTypeAlias(cast<DIDerivedType>(Ty));1666case dwarf::DW_TAG_base_type:1667return lowerTypeBasic(cast<DIBasicType>(Ty));1668case dwarf::DW_TAG_pointer_type:1669if (cast<DIDerivedType>(Ty)->getName() == "__vtbl_ptr_type")1670return lowerTypeVFTableShape(cast<DIDerivedType>(Ty));1671[[fallthrough]];1672case dwarf::DW_TAG_reference_type:1673case dwarf::DW_TAG_rvalue_reference_type:1674return lowerTypePointer(cast<DIDerivedType>(Ty));1675case dwarf::DW_TAG_ptr_to_member_type:1676return lowerTypeMemberPointer(cast<DIDerivedType>(Ty));1677case dwarf::DW_TAG_restrict_type:1678case dwarf::DW_TAG_const_type:1679case dwarf::DW_TAG_volatile_type:1680// TODO: add support for DW_TAG_atomic_type here1681return lowerTypeModifier(cast<DIDerivedType>(Ty));1682case dwarf::DW_TAG_subroutine_type:1683if (ClassTy) {1684// The member function type of a member function pointer has no1685// ThisAdjustment.1686return lowerTypeMemberFunction(cast<DISubroutineType>(Ty), ClassTy,1687/*ThisAdjustment=*/0,1688/*IsStaticMethod=*/false);1689}1690return lowerTypeFunction(cast<DISubroutineType>(Ty));1691case dwarf::DW_TAG_enumeration_type:1692return lowerTypeEnum(cast<DICompositeType>(Ty));1693case dwarf::DW_TAG_class_type:1694case dwarf::DW_TAG_structure_type:1695return lowerTypeClass(cast<DICompositeType>(Ty));1696case dwarf::DW_TAG_union_type:1697return lowerTypeUnion(cast<DICompositeType>(Ty));1698case dwarf::DW_TAG_string_type:1699return lowerTypeString(cast<DIStringType>(Ty));1700case dwarf::DW_TAG_unspecified_type:1701if (Ty->getName() == "decltype(nullptr)")1702return TypeIndex::NullptrT();1703return TypeIndex::None();1704default:1705// Use the null type index.1706return TypeIndex();1707}1708}17091710TypeIndex CodeViewDebug::lowerTypeAlias(const DIDerivedType *Ty) {1711TypeIndex UnderlyingTypeIndex = getTypeIndex(Ty->getBaseType());1712StringRef TypeName = Ty->getName();17131714addToUDTs(Ty);17151716if (UnderlyingTypeIndex == TypeIndex(SimpleTypeKind::Int32Long) &&1717TypeName == "HRESULT")1718return TypeIndex(SimpleTypeKind::HResult);1719if (UnderlyingTypeIndex == TypeIndex(SimpleTypeKind::UInt16Short) &&1720TypeName == "wchar_t")1721return TypeIndex(SimpleTypeKind::WideCharacter);17221723return UnderlyingTypeIndex;1724}17251726TypeIndex CodeViewDebug::lowerTypeArray(const DICompositeType *Ty) {1727const DIType *ElementType = Ty->getBaseType();1728TypeIndex ElementTypeIndex = getTypeIndex(ElementType);1729// IndexType is size_t, which depends on the bitness of the target.1730TypeIndex IndexType = getPointerSizeInBytes() == 81731? TypeIndex(SimpleTypeKind::UInt64Quad)1732: TypeIndex(SimpleTypeKind::UInt32Long);17331734uint64_t ElementSize = getBaseTypeSize(ElementType) / 8;17351736// Add subranges to array type.1737DINodeArray Elements = Ty->getElements();1738for (int i = Elements.size() - 1; i >= 0; --i) {1739const DINode *Element = Elements[i];1740assert(Element->getTag() == dwarf::DW_TAG_subrange_type);17411742const DISubrange *Subrange = cast<DISubrange>(Element);1743int64_t Count = -1;17441745// If Subrange has a Count field, use it.1746// Otherwise, if it has an upperboud, use (upperbound - lowerbound + 1),1747// where lowerbound is from the LowerBound field of the Subrange,1748// or the language default lowerbound if that field is unspecified.1749if (auto *CI = dyn_cast_if_present<ConstantInt *>(Subrange->getCount()))1750Count = CI->getSExtValue();1751else if (auto *UI = dyn_cast_if_present<ConstantInt *>(1752Subrange->getUpperBound())) {1753// Fortran uses 1 as the default lowerbound; other languages use 0.1754int64_t Lowerbound = (moduleIsInFortran()) ? 1 : 0;1755auto *LI = dyn_cast_if_present<ConstantInt *>(Subrange->getLowerBound());1756Lowerbound = (LI) ? LI->getSExtValue() : Lowerbound;1757Count = UI->getSExtValue() - Lowerbound + 1;1758}17591760// Forward declarations of arrays without a size and VLAs use a count of -1.1761// Emit a count of zero in these cases to match what MSVC does for arrays1762// without a size. MSVC doesn't support VLAs, so it's not clear what we1763// should do for them even if we could distinguish them.1764if (Count == -1)1765Count = 0;17661767// Update the element size and element type index for subsequent subranges.1768ElementSize *= Count;17691770// If this is the outermost array, use the size from the array. It will be1771// more accurate if we had a VLA or an incomplete element type size.1772uint64_t ArraySize =1773(i == 0 && ElementSize == 0) ? Ty->getSizeInBits() / 8 : ElementSize;17741775StringRef Name = (i == 0) ? Ty->getName() : "";1776ArrayRecord AR(ElementTypeIndex, IndexType, ArraySize, Name);1777ElementTypeIndex = TypeTable.writeLeafType(AR);1778}17791780return ElementTypeIndex;1781}17821783// This function lowers a Fortran character type (DIStringType).1784// Note that it handles only the character*n variant (using SizeInBits1785// field in DIString to describe the type size) at the moment.1786// Other variants (leveraging the StringLength and StringLengthExp1787// fields in DIStringType) remain TBD.1788TypeIndex CodeViewDebug::lowerTypeString(const DIStringType *Ty) {1789TypeIndex CharType = TypeIndex(SimpleTypeKind::NarrowCharacter);1790uint64_t ArraySize = Ty->getSizeInBits() >> 3;1791StringRef Name = Ty->getName();1792// IndexType is size_t, which depends on the bitness of the target.1793TypeIndex IndexType = getPointerSizeInBytes() == 81794? TypeIndex(SimpleTypeKind::UInt64Quad)1795: TypeIndex(SimpleTypeKind::UInt32Long);17961797// Create a type of character array of ArraySize.1798ArrayRecord AR(CharType, IndexType, ArraySize, Name);17991800return TypeTable.writeLeafType(AR);1801}18021803TypeIndex CodeViewDebug::lowerTypeBasic(const DIBasicType *Ty) {1804TypeIndex Index;1805dwarf::TypeKind Kind;1806uint32_t ByteSize;18071808Kind = static_cast<dwarf::TypeKind>(Ty->getEncoding());1809ByteSize = Ty->getSizeInBits() / 8;18101811SimpleTypeKind STK = SimpleTypeKind::None;1812switch (Kind) {1813case dwarf::DW_ATE_address:1814// FIXME: Translate1815break;1816case dwarf::DW_ATE_boolean:1817switch (ByteSize) {1818case 1: STK = SimpleTypeKind::Boolean8; break;1819case 2: STK = SimpleTypeKind::Boolean16; break;1820case 4: STK = SimpleTypeKind::Boolean32; break;1821case 8: STK = SimpleTypeKind::Boolean64; break;1822case 16: STK = SimpleTypeKind::Boolean128; break;1823}1824break;1825case dwarf::DW_ATE_complex_float:1826// The CodeView size for a complex represents the size of1827// an individual component.1828switch (ByteSize) {1829case 4: STK = SimpleTypeKind::Complex16; break;1830case 8: STK = SimpleTypeKind::Complex32; break;1831case 16: STK = SimpleTypeKind::Complex64; break;1832case 20: STK = SimpleTypeKind::Complex80; break;1833case 32: STK = SimpleTypeKind::Complex128; break;1834}1835break;1836case dwarf::DW_ATE_float:1837switch (ByteSize) {1838case 2: STK = SimpleTypeKind::Float16; break;1839case 4: STK = SimpleTypeKind::Float32; break;1840case 6: STK = SimpleTypeKind::Float48; break;1841case 8: STK = SimpleTypeKind::Float64; break;1842case 10: STK = SimpleTypeKind::Float80; break;1843case 16: STK = SimpleTypeKind::Float128; break;1844}1845break;1846case dwarf::DW_ATE_signed:1847switch (ByteSize) {1848case 1: STK = SimpleTypeKind::SignedCharacter; break;1849case 2: STK = SimpleTypeKind::Int16Short; break;1850case 4: STK = SimpleTypeKind::Int32; break;1851case 8: STK = SimpleTypeKind::Int64Quad; break;1852case 16: STK = SimpleTypeKind::Int128Oct; break;1853}1854break;1855case dwarf::DW_ATE_unsigned:1856switch (ByteSize) {1857case 1: STK = SimpleTypeKind::UnsignedCharacter; break;1858case 2: STK = SimpleTypeKind::UInt16Short; break;1859case 4: STK = SimpleTypeKind::UInt32; break;1860case 8: STK = SimpleTypeKind::UInt64Quad; break;1861case 16: STK = SimpleTypeKind::UInt128Oct; break;1862}1863break;1864case dwarf::DW_ATE_UTF:1865switch (ByteSize) {1866case 1: STK = SimpleTypeKind::Character8; break;1867case 2: STK = SimpleTypeKind::Character16; break;1868case 4: STK = SimpleTypeKind::Character32; break;1869}1870break;1871case dwarf::DW_ATE_signed_char:1872if (ByteSize == 1)1873STK = SimpleTypeKind::SignedCharacter;1874break;1875case dwarf::DW_ATE_unsigned_char:1876if (ByteSize == 1)1877STK = SimpleTypeKind::UnsignedCharacter;1878break;1879default:1880break;1881}18821883// Apply some fixups based on the source-level type name.1884// Include some amount of canonicalization from an old naming scheme Clang1885// used to use for integer types (in an outdated effort to be compatible with1886// GCC's debug info/GDB's behavior, which has since been addressed).1887if (STK == SimpleTypeKind::Int32 &&1888(Ty->getName() == "long int" || Ty->getName() == "long"))1889STK = SimpleTypeKind::Int32Long;1890if (STK == SimpleTypeKind::UInt32 && (Ty->getName() == "long unsigned int" ||1891Ty->getName() == "unsigned long"))1892STK = SimpleTypeKind::UInt32Long;1893if (STK == SimpleTypeKind::UInt16Short &&1894(Ty->getName() == "wchar_t" || Ty->getName() == "__wchar_t"))1895STK = SimpleTypeKind::WideCharacter;1896if ((STK == SimpleTypeKind::SignedCharacter ||1897STK == SimpleTypeKind::UnsignedCharacter) &&1898Ty->getName() == "char")1899STK = SimpleTypeKind::NarrowCharacter;19001901return TypeIndex(STK);1902}19031904TypeIndex CodeViewDebug::lowerTypePointer(const DIDerivedType *Ty,1905PointerOptions PO) {1906TypeIndex PointeeTI = getTypeIndex(Ty->getBaseType());19071908// Pointers to simple types without any options can use SimpleTypeMode, rather1909// than having a dedicated pointer type record.1910if (PointeeTI.isSimple() && PO == PointerOptions::None &&1911PointeeTI.getSimpleMode() == SimpleTypeMode::Direct &&1912Ty->getTag() == dwarf::DW_TAG_pointer_type) {1913SimpleTypeMode Mode = Ty->getSizeInBits() == 641914? SimpleTypeMode::NearPointer641915: SimpleTypeMode::NearPointer32;1916return TypeIndex(PointeeTI.getSimpleKind(), Mode);1917}19181919PointerKind PK =1920Ty->getSizeInBits() == 64 ? PointerKind::Near64 : PointerKind::Near32;1921PointerMode PM = PointerMode::Pointer;1922switch (Ty->getTag()) {1923default: llvm_unreachable("not a pointer tag type");1924case dwarf::DW_TAG_pointer_type:1925PM = PointerMode::Pointer;1926break;1927case dwarf::DW_TAG_reference_type:1928PM = PointerMode::LValueReference;1929break;1930case dwarf::DW_TAG_rvalue_reference_type:1931PM = PointerMode::RValueReference;1932break;1933}19341935if (Ty->isObjectPointer())1936PO |= PointerOptions::Const;19371938PointerRecord PR(PointeeTI, PK, PM, PO, Ty->getSizeInBits() / 8);1939return TypeTable.writeLeafType(PR);1940}19411942static PointerToMemberRepresentation1943translatePtrToMemberRep(unsigned SizeInBytes, bool IsPMF, unsigned Flags) {1944// SizeInBytes being zero generally implies that the member pointer type was1945// incomplete, which can happen if it is part of a function prototype. In this1946// case, use the unknown model instead of the general model.1947if (IsPMF) {1948switch (Flags & DINode::FlagPtrToMemberRep) {1949case 0:1950return SizeInBytes == 0 ? PointerToMemberRepresentation::Unknown1951: PointerToMemberRepresentation::GeneralFunction;1952case DINode::FlagSingleInheritance:1953return PointerToMemberRepresentation::SingleInheritanceFunction;1954case DINode::FlagMultipleInheritance:1955return PointerToMemberRepresentation::MultipleInheritanceFunction;1956case DINode::FlagVirtualInheritance:1957return PointerToMemberRepresentation::VirtualInheritanceFunction;1958}1959} else {1960switch (Flags & DINode::FlagPtrToMemberRep) {1961case 0:1962return SizeInBytes == 0 ? PointerToMemberRepresentation::Unknown1963: PointerToMemberRepresentation::GeneralData;1964case DINode::FlagSingleInheritance:1965return PointerToMemberRepresentation::SingleInheritanceData;1966case DINode::FlagMultipleInheritance:1967return PointerToMemberRepresentation::MultipleInheritanceData;1968case DINode::FlagVirtualInheritance:1969return PointerToMemberRepresentation::VirtualInheritanceData;1970}1971}1972llvm_unreachable("invalid ptr to member representation");1973}19741975TypeIndex CodeViewDebug::lowerTypeMemberPointer(const DIDerivedType *Ty,1976PointerOptions PO) {1977assert(Ty->getTag() == dwarf::DW_TAG_ptr_to_member_type);1978bool IsPMF = isa<DISubroutineType>(Ty->getBaseType());1979TypeIndex ClassTI = getTypeIndex(Ty->getClassType());1980TypeIndex PointeeTI =1981getTypeIndex(Ty->getBaseType(), IsPMF ? Ty->getClassType() : nullptr);1982PointerKind PK = getPointerSizeInBytes() == 8 ? PointerKind::Near641983: PointerKind::Near32;1984PointerMode PM = IsPMF ? PointerMode::PointerToMemberFunction1985: PointerMode::PointerToDataMember;19861987assert(Ty->getSizeInBits() / 8 <= 0xff && "pointer size too big");1988uint8_t SizeInBytes = Ty->getSizeInBits() / 8;1989MemberPointerInfo MPI(1990ClassTI, translatePtrToMemberRep(SizeInBytes, IsPMF, Ty->getFlags()));1991PointerRecord PR(PointeeTI, PK, PM, PO, SizeInBytes, MPI);1992return TypeTable.writeLeafType(PR);1993}19941995/// Given a DWARF calling convention, get the CodeView equivalent. If we don't1996/// have a translation, use the NearC convention.1997static CallingConvention dwarfCCToCodeView(unsigned DwarfCC) {1998switch (DwarfCC) {1999case dwarf::DW_CC_normal: return CallingConvention::NearC;2000case dwarf::DW_CC_BORLAND_msfastcall: return CallingConvention::NearFast;2001case dwarf::DW_CC_BORLAND_thiscall: return CallingConvention::ThisCall;2002case dwarf::DW_CC_BORLAND_stdcall: return CallingConvention::NearStdCall;2003case dwarf::DW_CC_BORLAND_pascal: return CallingConvention::NearPascal;2004case dwarf::DW_CC_LLVM_vectorcall: return CallingConvention::NearVector;2005}2006return CallingConvention::NearC;2007}20082009TypeIndex CodeViewDebug::lowerTypeModifier(const DIDerivedType *Ty) {2010ModifierOptions Mods = ModifierOptions::None;2011PointerOptions PO = PointerOptions::None;2012bool IsModifier = true;2013const DIType *BaseTy = Ty;2014while (IsModifier && BaseTy) {2015// FIXME: Need to add DWARF tags for __unaligned and _Atomic2016switch (BaseTy->getTag()) {2017case dwarf::DW_TAG_const_type:2018Mods |= ModifierOptions::Const;2019PO |= PointerOptions::Const;2020break;2021case dwarf::DW_TAG_volatile_type:2022Mods |= ModifierOptions::Volatile;2023PO |= PointerOptions::Volatile;2024break;2025case dwarf::DW_TAG_restrict_type:2026// Only pointer types be marked with __restrict. There is no known flag2027// for __restrict in LF_MODIFIER records.2028PO |= PointerOptions::Restrict;2029break;2030default:2031IsModifier = false;2032break;2033}2034if (IsModifier)2035BaseTy = cast<DIDerivedType>(BaseTy)->getBaseType();2036}20372038// Check if the inner type will use an LF_POINTER record. If so, the2039// qualifiers will go in the LF_POINTER record. This comes up for types like2040// 'int *const' and 'int *__restrict', not the more common cases like 'const2041// char *'.2042if (BaseTy) {2043switch (BaseTy->getTag()) {2044case dwarf::DW_TAG_pointer_type:2045case dwarf::DW_TAG_reference_type:2046case dwarf::DW_TAG_rvalue_reference_type:2047return lowerTypePointer(cast<DIDerivedType>(BaseTy), PO);2048case dwarf::DW_TAG_ptr_to_member_type:2049return lowerTypeMemberPointer(cast<DIDerivedType>(BaseTy), PO);2050default:2051break;2052}2053}20542055TypeIndex ModifiedTI = getTypeIndex(BaseTy);20562057// Return the base type index if there aren't any modifiers. For example, the2058// metadata could contain restrict wrappers around non-pointer types.2059if (Mods == ModifierOptions::None)2060return ModifiedTI;20612062ModifierRecord MR(ModifiedTI, Mods);2063return TypeTable.writeLeafType(MR);2064}20652066TypeIndex CodeViewDebug::lowerTypeFunction(const DISubroutineType *Ty) {2067SmallVector<TypeIndex, 8> ReturnAndArgTypeIndices;2068for (const DIType *ArgType : Ty->getTypeArray())2069ReturnAndArgTypeIndices.push_back(getTypeIndex(ArgType));20702071// MSVC uses type none for variadic argument.2072if (ReturnAndArgTypeIndices.size() > 1 &&2073ReturnAndArgTypeIndices.back() == TypeIndex::Void()) {2074ReturnAndArgTypeIndices.back() = TypeIndex::None();2075}2076TypeIndex ReturnTypeIndex = TypeIndex::Void();2077ArrayRef<TypeIndex> ArgTypeIndices = std::nullopt;2078if (!ReturnAndArgTypeIndices.empty()) {2079auto ReturnAndArgTypesRef = ArrayRef(ReturnAndArgTypeIndices);2080ReturnTypeIndex = ReturnAndArgTypesRef.front();2081ArgTypeIndices = ReturnAndArgTypesRef.drop_front();2082}20832084ArgListRecord ArgListRec(TypeRecordKind::ArgList, ArgTypeIndices);2085TypeIndex ArgListIndex = TypeTable.writeLeafType(ArgListRec);20862087CallingConvention CC = dwarfCCToCodeView(Ty->getCC());20882089FunctionOptions FO = getFunctionOptions(Ty);2090ProcedureRecord Procedure(ReturnTypeIndex, CC, FO, ArgTypeIndices.size(),2091ArgListIndex);2092return TypeTable.writeLeafType(Procedure);2093}20942095TypeIndex CodeViewDebug::lowerTypeMemberFunction(const DISubroutineType *Ty,2096const DIType *ClassTy,2097int ThisAdjustment,2098bool IsStaticMethod,2099FunctionOptions FO) {2100// Lower the containing class type.2101TypeIndex ClassType = getTypeIndex(ClassTy);21022103DITypeRefArray ReturnAndArgs = Ty->getTypeArray();21042105unsigned Index = 0;2106SmallVector<TypeIndex, 8> ArgTypeIndices;2107TypeIndex ReturnTypeIndex = TypeIndex::Void();2108if (ReturnAndArgs.size() > Index) {2109ReturnTypeIndex = getTypeIndex(ReturnAndArgs[Index++]);2110}21112112// If the first argument is a pointer type and this isn't a static method,2113// treat it as the special 'this' parameter, which is encoded separately from2114// the arguments.2115TypeIndex ThisTypeIndex;2116if (!IsStaticMethod && ReturnAndArgs.size() > Index) {2117if (const DIDerivedType *PtrTy =2118dyn_cast_or_null<DIDerivedType>(ReturnAndArgs[Index])) {2119if (PtrTy->getTag() == dwarf::DW_TAG_pointer_type) {2120ThisTypeIndex = getTypeIndexForThisPtr(PtrTy, Ty);2121Index++;2122}2123}2124}21252126while (Index < ReturnAndArgs.size())2127ArgTypeIndices.push_back(getTypeIndex(ReturnAndArgs[Index++]));21282129// MSVC uses type none for variadic argument.2130if (!ArgTypeIndices.empty() && ArgTypeIndices.back() == TypeIndex::Void())2131ArgTypeIndices.back() = TypeIndex::None();21322133ArgListRecord ArgListRec(TypeRecordKind::ArgList, ArgTypeIndices);2134TypeIndex ArgListIndex = TypeTable.writeLeafType(ArgListRec);21352136CallingConvention CC = dwarfCCToCodeView(Ty->getCC());21372138MemberFunctionRecord MFR(ReturnTypeIndex, ClassType, ThisTypeIndex, CC, FO,2139ArgTypeIndices.size(), ArgListIndex, ThisAdjustment);2140return TypeTable.writeLeafType(MFR);2141}21422143TypeIndex CodeViewDebug::lowerTypeVFTableShape(const DIDerivedType *Ty) {2144unsigned VSlotCount =2145Ty->getSizeInBits() / (8 * Asm->MAI->getCodePointerSize());2146SmallVector<VFTableSlotKind, 4> Slots(VSlotCount, VFTableSlotKind::Near);21472148VFTableShapeRecord VFTSR(Slots);2149return TypeTable.writeLeafType(VFTSR);2150}21512152static MemberAccess translateAccessFlags(unsigned RecordTag, unsigned Flags) {2153switch (Flags & DINode::FlagAccessibility) {2154case DINode::FlagPrivate: return MemberAccess::Private;2155case DINode::FlagPublic: return MemberAccess::Public;2156case DINode::FlagProtected: return MemberAccess::Protected;2157case 0:2158// If there was no explicit access control, provide the default for the tag.2159return RecordTag == dwarf::DW_TAG_class_type ? MemberAccess::Private2160: MemberAccess::Public;2161}2162llvm_unreachable("access flags are exclusive");2163}21642165static MethodOptions translateMethodOptionFlags(const DISubprogram *SP) {2166if (SP->isArtificial())2167return MethodOptions::CompilerGenerated;21682169// FIXME: Handle other MethodOptions.21702171return MethodOptions::None;2172}21732174static MethodKind translateMethodKindFlags(const DISubprogram *SP,2175bool Introduced) {2176if (SP->getFlags() & DINode::FlagStaticMember)2177return MethodKind::Static;21782179switch (SP->getVirtuality()) {2180case dwarf::DW_VIRTUALITY_none:2181break;2182case dwarf::DW_VIRTUALITY_virtual:2183return Introduced ? MethodKind::IntroducingVirtual : MethodKind::Virtual;2184case dwarf::DW_VIRTUALITY_pure_virtual:2185return Introduced ? MethodKind::PureIntroducingVirtual2186: MethodKind::PureVirtual;2187default:2188llvm_unreachable("unhandled virtuality case");2189}21902191return MethodKind::Vanilla;2192}21932194static TypeRecordKind getRecordKind(const DICompositeType *Ty) {2195switch (Ty->getTag()) {2196case dwarf::DW_TAG_class_type:2197return TypeRecordKind::Class;2198case dwarf::DW_TAG_structure_type:2199return TypeRecordKind::Struct;2200default:2201llvm_unreachable("unexpected tag");2202}2203}22042205/// Return ClassOptions that should be present on both the forward declaration2206/// and the defintion of a tag type.2207static ClassOptions getCommonClassOptions(const DICompositeType *Ty) {2208ClassOptions CO = ClassOptions::None;22092210// MSVC always sets this flag, even for local types. Clang doesn't always2211// appear to give every type a linkage name, which may be problematic for us.2212// FIXME: Investigate the consequences of not following them here.2213if (!Ty->getIdentifier().empty())2214CO |= ClassOptions::HasUniqueName;22152216// Put the Nested flag on a type if it appears immediately inside a tag type.2217// Do not walk the scope chain. Do not attempt to compute ContainsNestedClass2218// here. That flag is only set on definitions, and not forward declarations.2219const DIScope *ImmediateScope = Ty->getScope();2220if (ImmediateScope && isa<DICompositeType>(ImmediateScope))2221CO |= ClassOptions::Nested;22222223// Put the Scoped flag on function-local types. MSVC puts this flag for enum2224// type only when it has an immediate function scope. Clang never puts enums2225// inside DILexicalBlock scopes. Enum types, as generated by clang, are2226// always in function, class, or file scopes.2227if (Ty->getTag() == dwarf::DW_TAG_enumeration_type) {2228if (ImmediateScope && isa<DISubprogram>(ImmediateScope))2229CO |= ClassOptions::Scoped;2230} else {2231for (const DIScope *Scope = ImmediateScope; Scope != nullptr;2232Scope = Scope->getScope()) {2233if (isa<DISubprogram>(Scope)) {2234CO |= ClassOptions::Scoped;2235break;2236}2237}2238}22392240return CO;2241}22422243void CodeViewDebug::addUDTSrcLine(const DIType *Ty, TypeIndex TI) {2244switch (Ty->getTag()) {2245case dwarf::DW_TAG_class_type:2246case dwarf::DW_TAG_structure_type:2247case dwarf::DW_TAG_union_type:2248case dwarf::DW_TAG_enumeration_type:2249break;2250default:2251return;2252}22532254if (const auto *File = Ty->getFile()) {2255StringIdRecord SIDR(TypeIndex(0x0), getFullFilepath(File));2256TypeIndex SIDI = TypeTable.writeLeafType(SIDR);22572258UdtSourceLineRecord USLR(TI, SIDI, Ty->getLine());2259TypeTable.writeLeafType(USLR);2260}2261}22622263TypeIndex CodeViewDebug::lowerTypeEnum(const DICompositeType *Ty) {2264ClassOptions CO = getCommonClassOptions(Ty);2265TypeIndex FTI;2266unsigned EnumeratorCount = 0;22672268if (Ty->isForwardDecl()) {2269CO |= ClassOptions::ForwardReference;2270} else {2271ContinuationRecordBuilder ContinuationBuilder;2272ContinuationBuilder.begin(ContinuationRecordKind::FieldList);2273for (const DINode *Element : Ty->getElements()) {2274// We assume that the frontend provides all members in source declaration2275// order, which is what MSVC does.2276if (auto *Enumerator = dyn_cast_or_null<DIEnumerator>(Element)) {2277// FIXME: Is it correct to always emit these as unsigned here?2278EnumeratorRecord ER(MemberAccess::Public,2279APSInt(Enumerator->getValue(), true),2280Enumerator->getName());2281ContinuationBuilder.writeMemberType(ER);2282EnumeratorCount++;2283}2284}2285FTI = TypeTable.insertRecord(ContinuationBuilder);2286}22872288std::string FullName = getFullyQualifiedName(Ty);22892290EnumRecord ER(EnumeratorCount, CO, FTI, FullName, Ty->getIdentifier(),2291getTypeIndex(Ty->getBaseType()));2292TypeIndex EnumTI = TypeTable.writeLeafType(ER);22932294addUDTSrcLine(Ty, EnumTI);22952296return EnumTI;2297}22982299//===----------------------------------------------------------------------===//2300// ClassInfo2301//===----------------------------------------------------------------------===//23022303struct llvm::ClassInfo {2304struct MemberInfo {2305const DIDerivedType *MemberTypeNode;2306uint64_t BaseOffset;2307};2308// [MemberInfo]2309using MemberList = std::vector<MemberInfo>;23102311using MethodsList = TinyPtrVector<const DISubprogram *>;2312// MethodName -> MethodsList2313using MethodsMap = MapVector<MDString *, MethodsList>;23142315/// Base classes.2316std::vector<const DIDerivedType *> Inheritance;23172318/// Direct members.2319MemberList Members;2320// Direct overloaded methods gathered by name.2321MethodsMap Methods;23222323TypeIndex VShapeTI;23242325std::vector<const DIType *> NestedTypes;2326};23272328void CodeViewDebug::clear() {2329assert(CurFn == nullptr);2330FileIdMap.clear();2331FnDebugInfo.clear();2332FileToFilepathMap.clear();2333LocalUDTs.clear();2334GlobalUDTs.clear();2335TypeIndices.clear();2336CompleteTypeIndices.clear();2337ScopeGlobals.clear();2338CVGlobalVariableOffsets.clear();2339}23402341void CodeViewDebug::collectMemberInfo(ClassInfo &Info,2342const DIDerivedType *DDTy) {2343if (!DDTy->getName().empty()) {2344Info.Members.push_back({DDTy, 0});23452346// Collect static const data members with values.2347if ((DDTy->getFlags() & DINode::FlagStaticMember) ==2348DINode::FlagStaticMember) {2349if (DDTy->getConstant() && (isa<ConstantInt>(DDTy->getConstant()) ||2350isa<ConstantFP>(DDTy->getConstant())))2351StaticConstMembers.push_back(DDTy);2352}23532354return;2355}23562357// An unnamed member may represent a nested struct or union. Attempt to2358// interpret the unnamed member as a DICompositeType possibly wrapped in2359// qualifier types. Add all the indirect fields to the current record if that2360// succeeds, and drop the member if that fails.2361assert((DDTy->getOffsetInBits() % 8) == 0 && "Unnamed bitfield member!");2362uint64_t Offset = DDTy->getOffsetInBits();2363const DIType *Ty = DDTy->getBaseType();2364bool FullyResolved = false;2365while (!FullyResolved) {2366switch (Ty->getTag()) {2367case dwarf::DW_TAG_const_type:2368case dwarf::DW_TAG_volatile_type:2369// FIXME: we should apply the qualifier types to the indirect fields2370// rather than dropping them.2371Ty = cast<DIDerivedType>(Ty)->getBaseType();2372break;2373default:2374FullyResolved = true;2375break;2376}2377}23782379const DICompositeType *DCTy = dyn_cast<DICompositeType>(Ty);2380if (!DCTy)2381return;23822383ClassInfo NestedInfo = collectClassInfo(DCTy);2384for (const ClassInfo::MemberInfo &IndirectField : NestedInfo.Members)2385Info.Members.push_back(2386{IndirectField.MemberTypeNode, IndirectField.BaseOffset + Offset});2387}23882389ClassInfo CodeViewDebug::collectClassInfo(const DICompositeType *Ty) {2390ClassInfo Info;2391// Add elements to structure type.2392DINodeArray Elements = Ty->getElements();2393for (auto *Element : Elements) {2394// We assume that the frontend provides all members in source declaration2395// order, which is what MSVC does.2396if (!Element)2397continue;2398if (auto *SP = dyn_cast<DISubprogram>(Element)) {2399Info.Methods[SP->getRawName()].push_back(SP);2400} else if (auto *DDTy = dyn_cast<DIDerivedType>(Element)) {2401if (DDTy->getTag() == dwarf::DW_TAG_member) {2402collectMemberInfo(Info, DDTy);2403} else if (DDTy->getTag() == dwarf::DW_TAG_inheritance) {2404Info.Inheritance.push_back(DDTy);2405} else if (DDTy->getTag() == dwarf::DW_TAG_pointer_type &&2406DDTy->getName() == "__vtbl_ptr_type") {2407Info.VShapeTI = getTypeIndex(DDTy);2408} else if (DDTy->getTag() == dwarf::DW_TAG_typedef) {2409Info.NestedTypes.push_back(DDTy);2410} else if (DDTy->getTag() == dwarf::DW_TAG_friend) {2411// Ignore friend members. It appears that MSVC emitted info about2412// friends in the past, but modern versions do not.2413}2414} else if (auto *Composite = dyn_cast<DICompositeType>(Element)) {2415Info.NestedTypes.push_back(Composite);2416}2417// Skip other unrecognized kinds of elements.2418}2419return Info;2420}24212422static bool shouldAlwaysEmitCompleteClassType(const DICompositeType *Ty) {2423// This routine is used by lowerTypeClass and lowerTypeUnion to determine2424// if a complete type should be emitted instead of a forward reference.2425return Ty->getName().empty() && Ty->getIdentifier().empty() &&2426!Ty->isForwardDecl();2427}24282429TypeIndex CodeViewDebug::lowerTypeClass(const DICompositeType *Ty) {2430// Emit the complete type for unnamed structs. C++ classes with methods2431// which have a circular reference back to the class type are expected to2432// be named by the front-end and should not be "unnamed". C unnamed2433// structs should not have circular references.2434if (shouldAlwaysEmitCompleteClassType(Ty)) {2435// If this unnamed complete type is already in the process of being defined2436// then the description of the type is malformed and cannot be emitted2437// into CodeView correctly so report a fatal error.2438auto I = CompleteTypeIndices.find(Ty);2439if (I != CompleteTypeIndices.end() && I->second == TypeIndex())2440report_fatal_error("cannot debug circular reference to unnamed type");2441return getCompleteTypeIndex(Ty);2442}24432444// First, construct the forward decl. Don't look into Ty to compute the2445// forward decl options, since it might not be available in all TUs.2446TypeRecordKind Kind = getRecordKind(Ty);2447ClassOptions CO =2448ClassOptions::ForwardReference | getCommonClassOptions(Ty);2449std::string FullName = getFullyQualifiedName(Ty);2450ClassRecord CR(Kind, 0, CO, TypeIndex(), TypeIndex(), TypeIndex(), 0,2451FullName, Ty->getIdentifier());2452TypeIndex FwdDeclTI = TypeTable.writeLeafType(CR);2453if (!Ty->isForwardDecl())2454DeferredCompleteTypes.push_back(Ty);2455return FwdDeclTI;2456}24572458TypeIndex CodeViewDebug::lowerCompleteTypeClass(const DICompositeType *Ty) {2459// Construct the field list and complete type record.2460TypeRecordKind Kind = getRecordKind(Ty);2461ClassOptions CO = getCommonClassOptions(Ty);2462TypeIndex FieldTI;2463TypeIndex VShapeTI;2464unsigned FieldCount;2465bool ContainsNestedClass;2466std::tie(FieldTI, VShapeTI, FieldCount, ContainsNestedClass) =2467lowerRecordFieldList(Ty);24682469if (ContainsNestedClass)2470CO |= ClassOptions::ContainsNestedClass;24712472// MSVC appears to set this flag by searching any destructor or method with2473// FunctionOptions::Constructor among the emitted members. Clang AST has all2474// the members, however special member functions are not yet emitted into2475// debug information. For now checking a class's non-triviality seems enough.2476// FIXME: not true for a nested unnamed struct.2477if (isNonTrivial(Ty))2478CO |= ClassOptions::HasConstructorOrDestructor;24792480std::string FullName = getFullyQualifiedName(Ty);24812482uint64_t SizeInBytes = Ty->getSizeInBits() / 8;24832484ClassRecord CR(Kind, FieldCount, CO, FieldTI, TypeIndex(), VShapeTI,2485SizeInBytes, FullName, Ty->getIdentifier());2486TypeIndex ClassTI = TypeTable.writeLeafType(CR);24872488addUDTSrcLine(Ty, ClassTI);24892490addToUDTs(Ty);24912492return ClassTI;2493}24942495TypeIndex CodeViewDebug::lowerTypeUnion(const DICompositeType *Ty) {2496// Emit the complete type for unnamed unions.2497if (shouldAlwaysEmitCompleteClassType(Ty))2498return getCompleteTypeIndex(Ty);24992500ClassOptions CO =2501ClassOptions::ForwardReference | getCommonClassOptions(Ty);2502std::string FullName = getFullyQualifiedName(Ty);2503UnionRecord UR(0, CO, TypeIndex(), 0, FullName, Ty->getIdentifier());2504TypeIndex FwdDeclTI = TypeTable.writeLeafType(UR);2505if (!Ty->isForwardDecl())2506DeferredCompleteTypes.push_back(Ty);2507return FwdDeclTI;2508}25092510TypeIndex CodeViewDebug::lowerCompleteTypeUnion(const DICompositeType *Ty) {2511ClassOptions CO = ClassOptions::Sealed | getCommonClassOptions(Ty);2512TypeIndex FieldTI;2513unsigned FieldCount;2514bool ContainsNestedClass;2515std::tie(FieldTI, std::ignore, FieldCount, ContainsNestedClass) =2516lowerRecordFieldList(Ty);25172518if (ContainsNestedClass)2519CO |= ClassOptions::ContainsNestedClass;25202521uint64_t SizeInBytes = Ty->getSizeInBits() / 8;2522std::string FullName = getFullyQualifiedName(Ty);25232524UnionRecord UR(FieldCount, CO, FieldTI, SizeInBytes, FullName,2525Ty->getIdentifier());2526TypeIndex UnionTI = TypeTable.writeLeafType(UR);25272528addUDTSrcLine(Ty, UnionTI);25292530addToUDTs(Ty);25312532return UnionTI;2533}25342535std::tuple<TypeIndex, TypeIndex, unsigned, bool>2536CodeViewDebug::lowerRecordFieldList(const DICompositeType *Ty) {2537// Manually count members. MSVC appears to count everything that generates a2538// field list record. Each individual overload in a method overload group2539// contributes to this count, even though the overload group is a single field2540// list record.2541unsigned MemberCount = 0;2542ClassInfo Info = collectClassInfo(Ty);2543ContinuationRecordBuilder ContinuationBuilder;2544ContinuationBuilder.begin(ContinuationRecordKind::FieldList);25452546// Create base classes.2547for (const DIDerivedType *I : Info.Inheritance) {2548if (I->getFlags() & DINode::FlagVirtual) {2549// Virtual base.2550unsigned VBPtrOffset = I->getVBPtrOffset();2551// FIXME: Despite the accessor name, the offset is really in bytes.2552unsigned VBTableIndex = I->getOffsetInBits() / 4;2553auto RecordKind = (I->getFlags() & DINode::FlagIndirectVirtualBase) == DINode::FlagIndirectVirtualBase2554? TypeRecordKind::IndirectVirtualBaseClass2555: TypeRecordKind::VirtualBaseClass;2556VirtualBaseClassRecord VBCR(2557RecordKind, translateAccessFlags(Ty->getTag(), I->getFlags()),2558getTypeIndex(I->getBaseType()), getVBPTypeIndex(), VBPtrOffset,2559VBTableIndex);25602561ContinuationBuilder.writeMemberType(VBCR);2562MemberCount++;2563} else {2564assert(I->getOffsetInBits() % 8 == 0 &&2565"bases must be on byte boundaries");2566BaseClassRecord BCR(translateAccessFlags(Ty->getTag(), I->getFlags()),2567getTypeIndex(I->getBaseType()),2568I->getOffsetInBits() / 8);2569ContinuationBuilder.writeMemberType(BCR);2570MemberCount++;2571}2572}25732574// Create members.2575for (ClassInfo::MemberInfo &MemberInfo : Info.Members) {2576const DIDerivedType *Member = MemberInfo.MemberTypeNode;2577TypeIndex MemberBaseType = getTypeIndex(Member->getBaseType());2578StringRef MemberName = Member->getName();2579MemberAccess Access =2580translateAccessFlags(Ty->getTag(), Member->getFlags());25812582if (Member->isStaticMember()) {2583StaticDataMemberRecord SDMR(Access, MemberBaseType, MemberName);2584ContinuationBuilder.writeMemberType(SDMR);2585MemberCount++;2586continue;2587}25882589// Virtual function pointer member.2590if ((Member->getFlags() & DINode::FlagArtificial) &&2591Member->getName().starts_with("_vptr$")) {2592VFPtrRecord VFPR(getTypeIndex(Member->getBaseType()));2593ContinuationBuilder.writeMemberType(VFPR);2594MemberCount++;2595continue;2596}25972598// Data member.2599uint64_t MemberOffsetInBits =2600Member->getOffsetInBits() + MemberInfo.BaseOffset;2601if (Member->isBitField()) {2602uint64_t StartBitOffset = MemberOffsetInBits;2603if (const auto *CI =2604dyn_cast_or_null<ConstantInt>(Member->getStorageOffsetInBits())) {2605MemberOffsetInBits = CI->getZExtValue() + MemberInfo.BaseOffset;2606}2607StartBitOffset -= MemberOffsetInBits;2608BitFieldRecord BFR(MemberBaseType, Member->getSizeInBits(),2609StartBitOffset);2610MemberBaseType = TypeTable.writeLeafType(BFR);2611}2612uint64_t MemberOffsetInBytes = MemberOffsetInBits / 8;2613DataMemberRecord DMR(Access, MemberBaseType, MemberOffsetInBytes,2614MemberName);2615ContinuationBuilder.writeMemberType(DMR);2616MemberCount++;2617}26182619// Create methods2620for (auto &MethodItr : Info.Methods) {2621StringRef Name = MethodItr.first->getString();26222623std::vector<OneMethodRecord> Methods;2624for (const DISubprogram *SP : MethodItr.second) {2625TypeIndex MethodType = getMemberFunctionType(SP, Ty);2626bool Introduced = SP->getFlags() & DINode::FlagIntroducedVirtual;26272628unsigned VFTableOffset = -1;2629if (Introduced)2630VFTableOffset = SP->getVirtualIndex() * getPointerSizeInBytes();26312632Methods.push_back(OneMethodRecord(2633MethodType, translateAccessFlags(Ty->getTag(), SP->getFlags()),2634translateMethodKindFlags(SP, Introduced),2635translateMethodOptionFlags(SP), VFTableOffset, Name));2636MemberCount++;2637}2638assert(!Methods.empty() && "Empty methods map entry");2639if (Methods.size() == 1)2640ContinuationBuilder.writeMemberType(Methods[0]);2641else {2642// FIXME: Make this use its own ContinuationBuilder so that2643// MethodOverloadList can be split correctly.2644MethodOverloadListRecord MOLR(Methods);2645TypeIndex MethodList = TypeTable.writeLeafType(MOLR);26462647OverloadedMethodRecord OMR(Methods.size(), MethodList, Name);2648ContinuationBuilder.writeMemberType(OMR);2649}2650}26512652// Create nested classes.2653for (const DIType *Nested : Info.NestedTypes) {2654NestedTypeRecord R(getTypeIndex(Nested), Nested->getName());2655ContinuationBuilder.writeMemberType(R);2656MemberCount++;2657}26582659TypeIndex FieldTI = TypeTable.insertRecord(ContinuationBuilder);2660return std::make_tuple(FieldTI, Info.VShapeTI, MemberCount,2661!Info.NestedTypes.empty());2662}26632664TypeIndex CodeViewDebug::getVBPTypeIndex() {2665if (!VBPType.getIndex()) {2666// Make a 'const int *' type.2667ModifierRecord MR(TypeIndex::Int32(), ModifierOptions::Const);2668TypeIndex ModifiedTI = TypeTable.writeLeafType(MR);26692670PointerKind PK = getPointerSizeInBytes() == 8 ? PointerKind::Near642671: PointerKind::Near32;2672PointerMode PM = PointerMode::Pointer;2673PointerOptions PO = PointerOptions::None;2674PointerRecord PR(ModifiedTI, PK, PM, PO, getPointerSizeInBytes());2675VBPType = TypeTable.writeLeafType(PR);2676}26772678return VBPType;2679}26802681TypeIndex CodeViewDebug::getTypeIndex(const DIType *Ty, const DIType *ClassTy) {2682// The null DIType is the void type. Don't try to hash it.2683if (!Ty)2684return TypeIndex::Void();26852686// Check if we've already translated this type. Don't try to do a2687// get-or-create style insertion that caches the hash lookup across the2688// lowerType call. It will update the TypeIndices map.2689auto I = TypeIndices.find({Ty, ClassTy});2690if (I != TypeIndices.end())2691return I->second;26922693TypeLoweringScope S(*this);2694TypeIndex TI = lowerType(Ty, ClassTy);2695return recordTypeIndexForDINode(Ty, TI, ClassTy);2696}26972698codeview::TypeIndex2699CodeViewDebug::getTypeIndexForThisPtr(const DIDerivedType *PtrTy,2700const DISubroutineType *SubroutineTy) {2701assert(PtrTy->getTag() == dwarf::DW_TAG_pointer_type &&2702"this type must be a pointer type");27032704PointerOptions Options = PointerOptions::None;2705if (SubroutineTy->getFlags() & DINode::DIFlags::FlagLValueReference)2706Options = PointerOptions::LValueRefThisPointer;2707else if (SubroutineTy->getFlags() & DINode::DIFlags::FlagRValueReference)2708Options = PointerOptions::RValueRefThisPointer;27092710// Check if we've already translated this type. If there is no ref qualifier2711// on the function then we look up this pointer type with no associated class2712// so that the TypeIndex for the this pointer can be shared with the type2713// index for other pointers to this class type. If there is a ref qualifier2714// then we lookup the pointer using the subroutine as the parent type.2715auto I = TypeIndices.find({PtrTy, SubroutineTy});2716if (I != TypeIndices.end())2717return I->second;27182719TypeLoweringScope S(*this);2720TypeIndex TI = lowerTypePointer(PtrTy, Options);2721return recordTypeIndexForDINode(PtrTy, TI, SubroutineTy);2722}27232724TypeIndex CodeViewDebug::getTypeIndexForReferenceTo(const DIType *Ty) {2725PointerRecord PR(getTypeIndex(Ty),2726getPointerSizeInBytes() == 8 ? PointerKind::Near642727: PointerKind::Near32,2728PointerMode::LValueReference, PointerOptions::None,2729Ty->getSizeInBits() / 8);2730return TypeTable.writeLeafType(PR);2731}27322733TypeIndex CodeViewDebug::getCompleteTypeIndex(const DIType *Ty) {2734// The null DIType is the void type. Don't try to hash it.2735if (!Ty)2736return TypeIndex::Void();27372738// Look through typedefs when getting the complete type index. Call2739// getTypeIndex on the typdef to ensure that any UDTs are accumulated and are2740// emitted only once.2741if (Ty->getTag() == dwarf::DW_TAG_typedef)2742(void)getTypeIndex(Ty);2743while (Ty->getTag() == dwarf::DW_TAG_typedef)2744Ty = cast<DIDerivedType>(Ty)->getBaseType();27452746// If this is a non-record type, the complete type index is the same as the2747// normal type index. Just call getTypeIndex.2748switch (Ty->getTag()) {2749case dwarf::DW_TAG_class_type:2750case dwarf::DW_TAG_structure_type:2751case dwarf::DW_TAG_union_type:2752break;2753default:2754return getTypeIndex(Ty);2755}27562757const auto *CTy = cast<DICompositeType>(Ty);27582759TypeLoweringScope S(*this);27602761// Make sure the forward declaration is emitted first. It's unclear if this2762// is necessary, but MSVC does it, and we should follow suit until we can show2763// otherwise.2764// We only emit a forward declaration for named types.2765if (!CTy->getName().empty() || !CTy->getIdentifier().empty()) {2766TypeIndex FwdDeclTI = getTypeIndex(CTy);27672768// Just use the forward decl if we don't have complete type info. This2769// might happen if the frontend is using modules and expects the complete2770// definition to be emitted elsewhere.2771if (CTy->isForwardDecl())2772return FwdDeclTI;2773}27742775// Check if we've already translated the complete record type.2776// Insert the type with a null TypeIndex to signify that the type is currently2777// being lowered.2778auto InsertResult = CompleteTypeIndices.insert({CTy, TypeIndex()});2779if (!InsertResult.second)2780return InsertResult.first->second;27812782TypeIndex TI;2783switch (CTy->getTag()) {2784case dwarf::DW_TAG_class_type:2785case dwarf::DW_TAG_structure_type:2786TI = lowerCompleteTypeClass(CTy);2787break;2788case dwarf::DW_TAG_union_type:2789TI = lowerCompleteTypeUnion(CTy);2790break;2791default:2792llvm_unreachable("not a record");2793}27942795// Update the type index associated with this CompositeType. This cannot2796// use the 'InsertResult' iterator above because it is potentially2797// invalidated by map insertions which can occur while lowering the class2798// type above.2799CompleteTypeIndices[CTy] = TI;2800return TI;2801}28022803/// Emit all the deferred complete record types. Try to do this in FIFO order,2804/// and do this until fixpoint, as each complete record type typically2805/// references2806/// many other record types.2807void CodeViewDebug::emitDeferredCompleteTypes() {2808SmallVector<const DICompositeType *, 4> TypesToEmit;2809while (!DeferredCompleteTypes.empty()) {2810std::swap(DeferredCompleteTypes, TypesToEmit);2811for (const DICompositeType *RecordTy : TypesToEmit)2812getCompleteTypeIndex(RecordTy);2813TypesToEmit.clear();2814}2815}28162817void CodeViewDebug::emitLocalVariableList(const FunctionInfo &FI,2818ArrayRef<LocalVariable> Locals) {2819// Get the sorted list of parameters and emit them first.2820SmallVector<const LocalVariable *, 6> Params;2821for (const LocalVariable &L : Locals)2822if (L.DIVar->isParameter())2823Params.push_back(&L);2824llvm::sort(Params, [](const LocalVariable *L, const LocalVariable *R) {2825return L->DIVar->getArg() < R->DIVar->getArg();2826});2827for (const LocalVariable *L : Params)2828emitLocalVariable(FI, *L);28292830// Next emit all non-parameters in the order that we found them.2831for (const LocalVariable &L : Locals) {2832if (!L.DIVar->isParameter()) {2833if (L.ConstantValue) {2834// If ConstantValue is set we will emit it as a S_CONSTANT instead of a2835// S_LOCAL in order to be able to represent it at all.2836const DIType *Ty = L.DIVar->getType();2837APSInt Val(*L.ConstantValue);2838emitConstantSymbolRecord(Ty, Val, std::string(L.DIVar->getName()));2839} else {2840emitLocalVariable(FI, L);2841}2842}2843}2844}28452846void CodeViewDebug::emitLocalVariable(const FunctionInfo &FI,2847const LocalVariable &Var) {2848// LocalSym record, see SymbolRecord.h for more info.2849MCSymbol *LocalEnd = beginSymbolRecord(SymbolKind::S_LOCAL);28502851LocalSymFlags Flags = LocalSymFlags::None;2852if (Var.DIVar->isParameter())2853Flags |= LocalSymFlags::IsParameter;2854if (Var.DefRanges.empty())2855Flags |= LocalSymFlags::IsOptimizedOut;28562857OS.AddComment("TypeIndex");2858TypeIndex TI = Var.UseReferenceType2859? getTypeIndexForReferenceTo(Var.DIVar->getType())2860: getCompleteTypeIndex(Var.DIVar->getType());2861OS.emitInt32(TI.getIndex());2862OS.AddComment("Flags");2863OS.emitInt16(static_cast<uint16_t>(Flags));2864// Truncate the name so we won't overflow the record length field.2865emitNullTerminatedSymbolName(OS, Var.DIVar->getName());2866endSymbolRecord(LocalEnd);28672868// Calculate the on disk prefix of the appropriate def range record. The2869// records and on disk formats are described in SymbolRecords.h. BytePrefix2870// should be big enough to hold all forms without memory allocation.2871SmallString<20> BytePrefix;2872for (const auto &Pair : Var.DefRanges) {2873LocalVarDef DefRange = Pair.first;2874const auto &Ranges = Pair.second;2875BytePrefix.clear();2876if (DefRange.InMemory) {2877int Offset = DefRange.DataOffset;2878unsigned Reg = DefRange.CVRegister;28792880// 32-bit x86 call sequences often use PUSH instructions, which disrupt2881// ESP-relative offsets. Use the virtual frame pointer, VFRAME or $T0,2882// instead. In frames without stack realignment, $T0 will be the CFA.2883if (RegisterId(Reg) == RegisterId::ESP) {2884Reg = unsigned(RegisterId::VFRAME);2885Offset += FI.OffsetAdjustment;2886}28872888// If we can use the chosen frame pointer for the frame and this isn't a2889// sliced aggregate, use the smaller S_DEFRANGE_FRAMEPOINTER_REL record.2890// Otherwise, use S_DEFRANGE_REGISTER_REL.2891EncodedFramePtrReg EncFP = encodeFramePtrReg(RegisterId(Reg), TheCPU);2892if (!DefRange.IsSubfield && EncFP != EncodedFramePtrReg::None &&2893(bool(Flags & LocalSymFlags::IsParameter)2894? (EncFP == FI.EncodedParamFramePtrReg)2895: (EncFP == FI.EncodedLocalFramePtrReg))) {2896DefRangeFramePointerRelHeader DRHdr;2897DRHdr.Offset = Offset;2898OS.emitCVDefRangeDirective(Ranges, DRHdr);2899} else {2900uint16_t RegRelFlags = 0;2901if (DefRange.IsSubfield) {2902RegRelFlags = DefRangeRegisterRelSym::IsSubfieldFlag |2903(DefRange.StructOffset2904<< DefRangeRegisterRelSym::OffsetInParentShift);2905}2906DefRangeRegisterRelHeader DRHdr;2907DRHdr.Register = Reg;2908DRHdr.Flags = RegRelFlags;2909DRHdr.BasePointerOffset = Offset;2910OS.emitCVDefRangeDirective(Ranges, DRHdr);2911}2912} else {2913assert(DefRange.DataOffset == 0 && "unexpected offset into register");2914if (DefRange.IsSubfield) {2915DefRangeSubfieldRegisterHeader DRHdr;2916DRHdr.Register = DefRange.CVRegister;2917DRHdr.MayHaveNoName = 0;2918DRHdr.OffsetInParent = DefRange.StructOffset;2919OS.emitCVDefRangeDirective(Ranges, DRHdr);2920} else {2921DefRangeRegisterHeader DRHdr;2922DRHdr.Register = DefRange.CVRegister;2923DRHdr.MayHaveNoName = 0;2924OS.emitCVDefRangeDirective(Ranges, DRHdr);2925}2926}2927}2928}29292930void CodeViewDebug::emitLexicalBlockList(ArrayRef<LexicalBlock *> Blocks,2931const FunctionInfo& FI) {2932for (LexicalBlock *Block : Blocks)2933emitLexicalBlock(*Block, FI);2934}29352936/// Emit an S_BLOCK32 and S_END record pair delimiting the contents of a2937/// lexical block scope.2938void CodeViewDebug::emitLexicalBlock(const LexicalBlock &Block,2939const FunctionInfo& FI) {2940MCSymbol *RecordEnd = beginSymbolRecord(SymbolKind::S_BLOCK32);2941OS.AddComment("PtrParent");2942OS.emitInt32(0); // PtrParent2943OS.AddComment("PtrEnd");2944OS.emitInt32(0); // PtrEnd2945OS.AddComment("Code size");2946OS.emitAbsoluteSymbolDiff(Block.End, Block.Begin, 4); // Code Size2947OS.AddComment("Function section relative address");2948OS.emitCOFFSecRel32(Block.Begin, /*Offset=*/0); // Func Offset2949OS.AddComment("Function section index");2950OS.emitCOFFSectionIndex(FI.Begin); // Func Symbol2951OS.AddComment("Lexical block name");2952emitNullTerminatedSymbolName(OS, Block.Name); // Name2953endSymbolRecord(RecordEnd);29542955// Emit variables local to this lexical block.2956emitLocalVariableList(FI, Block.Locals);2957emitGlobalVariableList(Block.Globals);29582959// Emit lexical blocks contained within this block.2960emitLexicalBlockList(Block.Children, FI);29612962// Close the lexical block scope.2963emitEndSymbolRecord(SymbolKind::S_END);2964}29652966/// Convenience routine for collecting lexical block information for a list2967/// of lexical scopes.2968void CodeViewDebug::collectLexicalBlockInfo(2969SmallVectorImpl<LexicalScope *> &Scopes,2970SmallVectorImpl<LexicalBlock *> &Blocks,2971SmallVectorImpl<LocalVariable> &Locals,2972SmallVectorImpl<CVGlobalVariable> &Globals) {2973for (LexicalScope *Scope : Scopes)2974collectLexicalBlockInfo(*Scope, Blocks, Locals, Globals);2975}29762977/// Populate the lexical blocks and local variable lists of the parent with2978/// information about the specified lexical scope.2979void CodeViewDebug::collectLexicalBlockInfo(2980LexicalScope &Scope,2981SmallVectorImpl<LexicalBlock *> &ParentBlocks,2982SmallVectorImpl<LocalVariable> &ParentLocals,2983SmallVectorImpl<CVGlobalVariable> &ParentGlobals) {2984if (Scope.isAbstractScope())2985return;29862987// Gather information about the lexical scope including local variables,2988// global variables, and address ranges.2989bool IgnoreScope = false;2990auto LI = ScopeVariables.find(&Scope);2991SmallVectorImpl<LocalVariable> *Locals =2992LI != ScopeVariables.end() ? &LI->second : nullptr;2993auto GI = ScopeGlobals.find(Scope.getScopeNode());2994SmallVectorImpl<CVGlobalVariable> *Globals =2995GI != ScopeGlobals.end() ? GI->second.get() : nullptr;2996const DILexicalBlock *DILB = dyn_cast<DILexicalBlock>(Scope.getScopeNode());2997const SmallVectorImpl<InsnRange> &Ranges = Scope.getRanges();29982999// Ignore lexical scopes which do not contain variables.3000if (!Locals && !Globals)3001IgnoreScope = true;30023003// Ignore lexical scopes which are not lexical blocks.3004if (!DILB)3005IgnoreScope = true;30063007// Ignore scopes which have too many address ranges to represent in the3008// current CodeView format or do not have a valid address range.3009//3010// For lexical scopes with multiple address ranges you may be tempted to3011// construct a single range covering every instruction where the block is3012// live and everything in between. Unfortunately, Visual Studio only3013// displays variables from the first matching lexical block scope. If the3014// first lexical block contains exception handling code or cold code which3015// is moved to the bottom of the routine creating a single range covering3016// nearly the entire routine, then it will hide all other lexical blocks3017// and the variables they contain.3018if (Ranges.size() != 1 || !getLabelAfterInsn(Ranges.front().second))3019IgnoreScope = true;30203021if (IgnoreScope) {3022// This scope can be safely ignored and eliminating it will reduce the3023// size of the debug information. Be sure to collect any variable and scope3024// information from the this scope or any of its children and collapse them3025// into the parent scope.3026if (Locals)3027ParentLocals.append(Locals->begin(), Locals->end());3028if (Globals)3029ParentGlobals.append(Globals->begin(), Globals->end());3030collectLexicalBlockInfo(Scope.getChildren(),3031ParentBlocks,3032ParentLocals,3033ParentGlobals);3034return;3035}30363037// Create a new CodeView lexical block for this lexical scope. If we've3038// seen this DILexicalBlock before then the scope tree is malformed and3039// we can handle this gracefully by not processing it a second time.3040auto BlockInsertion = CurFn->LexicalBlocks.insert({DILB, LexicalBlock()});3041if (!BlockInsertion.second)3042return;30433044// Create a lexical block containing the variables and collect the3045// lexical block information for the children.3046const InsnRange &Range = Ranges.front();3047assert(Range.first && Range.second);3048LexicalBlock &Block = BlockInsertion.first->second;3049Block.Begin = getLabelBeforeInsn(Range.first);3050Block.End = getLabelAfterInsn(Range.second);3051assert(Block.Begin && "missing label for scope begin");3052assert(Block.End && "missing label for scope end");3053Block.Name = DILB->getName();3054if (Locals)3055Block.Locals = std::move(*Locals);3056if (Globals)3057Block.Globals = std::move(*Globals);3058ParentBlocks.push_back(&Block);3059collectLexicalBlockInfo(Scope.getChildren(),3060Block.Children,3061Block.Locals,3062Block.Globals);3063}30643065void CodeViewDebug::endFunctionImpl(const MachineFunction *MF) {3066const Function &GV = MF->getFunction();3067assert(FnDebugInfo.count(&GV));3068assert(CurFn == FnDebugInfo[&GV].get());30693070collectVariableInfo(GV.getSubprogram());30713072// Build the lexical block structure to emit for this routine.3073if (LexicalScope *CFS = LScopes.getCurrentFunctionScope())3074collectLexicalBlockInfo(*CFS,3075CurFn->ChildBlocks,3076CurFn->Locals,3077CurFn->Globals);30783079// Clear the scope and variable information from the map which will not be3080// valid after we have finished processing this routine. This also prepares3081// the map for the subsequent routine.3082ScopeVariables.clear();30833084// Don't emit anything if we don't have any line tables.3085// Thunks are compiler-generated and probably won't have source correlation.3086if (!CurFn->HaveLineInfo && !GV.getSubprogram()->isThunk()) {3087FnDebugInfo.erase(&GV);3088CurFn = nullptr;3089return;3090}30913092// Find heap alloc sites and add to list.3093for (const auto &MBB : *MF) {3094for (const auto &MI : MBB) {3095if (MDNode *MD = MI.getHeapAllocMarker()) {3096CurFn->HeapAllocSites.push_back(std::make_tuple(getLabelBeforeInsn(&MI),3097getLabelAfterInsn(&MI),3098dyn_cast<DIType>(MD)));3099}3100}3101}31023103bool isThumb = Triple(MMI->getModule()->getTargetTriple()).getArch() ==3104llvm::Triple::ArchType::thumb;3105collectDebugInfoForJumpTables(MF, isThumb);31063107CurFn->Annotations = MF->getCodeViewAnnotations();31083109CurFn->End = Asm->getFunctionEnd();31103111CurFn = nullptr;3112}31133114// Usable locations are valid with non-zero line numbers. A line number of zero3115// corresponds to optimized code that doesn't have a distinct source location.3116// In this case, we try to use the previous or next source location depending on3117// the context.3118static bool isUsableDebugLoc(DebugLoc DL) {3119return DL && DL.getLine() != 0;3120}31213122void CodeViewDebug::beginInstruction(const MachineInstr *MI) {3123DebugHandlerBase::beginInstruction(MI);31243125// Ignore DBG_VALUE and DBG_LABEL locations and function prologue.3126if (!Asm || !CurFn || MI->isDebugInstr() ||3127MI->getFlag(MachineInstr::FrameSetup))3128return;31293130// If the first instruction of a new MBB has no location, find the first3131// instruction with a location and use that.3132DebugLoc DL = MI->getDebugLoc();3133if (!isUsableDebugLoc(DL) && MI->getParent() != PrevInstBB) {3134for (const auto &NextMI : *MI->getParent()) {3135if (NextMI.isDebugInstr())3136continue;3137DL = NextMI.getDebugLoc();3138if (isUsableDebugLoc(DL))3139break;3140}3141// FIXME: Handle the case where the BB has no valid locations. This would3142// probably require doing a real dataflow analysis.3143}3144PrevInstBB = MI->getParent();31453146// If we still don't have a debug location, don't record a location.3147if (!isUsableDebugLoc(DL))3148return;31493150maybeRecordLocation(DL, Asm->MF);3151}31523153MCSymbol *CodeViewDebug::beginCVSubsection(DebugSubsectionKind Kind) {3154MCSymbol *BeginLabel = MMI->getContext().createTempSymbol(),3155*EndLabel = MMI->getContext().createTempSymbol();3156OS.emitInt32(unsigned(Kind));3157OS.AddComment("Subsection size");3158OS.emitAbsoluteSymbolDiff(EndLabel, BeginLabel, 4);3159OS.emitLabel(BeginLabel);3160return EndLabel;3161}31623163void CodeViewDebug::endCVSubsection(MCSymbol *EndLabel) {3164OS.emitLabel(EndLabel);3165// Every subsection must be aligned to a 4-byte boundary.3166OS.emitValueToAlignment(Align(4));3167}31683169static StringRef getSymbolName(SymbolKind SymKind) {3170for (const EnumEntry<SymbolKind> &EE : getSymbolTypeNames())3171if (EE.Value == SymKind)3172return EE.Name;3173return "";3174}31753176MCSymbol *CodeViewDebug::beginSymbolRecord(SymbolKind SymKind) {3177MCSymbol *BeginLabel = MMI->getContext().createTempSymbol(),3178*EndLabel = MMI->getContext().createTempSymbol();3179OS.AddComment("Record length");3180OS.emitAbsoluteSymbolDiff(EndLabel, BeginLabel, 2);3181OS.emitLabel(BeginLabel);3182if (OS.isVerboseAsm())3183OS.AddComment("Record kind: " + getSymbolName(SymKind));3184OS.emitInt16(unsigned(SymKind));3185return EndLabel;3186}31873188void CodeViewDebug::endSymbolRecord(MCSymbol *SymEnd) {3189// MSVC does not pad out symbol records to four bytes, but LLVM does to avoid3190// an extra copy of every symbol record in LLD. This increases object file3191// size by less than 1% in the clang build, and is compatible with the Visual3192// C++ linker.3193OS.emitValueToAlignment(Align(4));3194OS.emitLabel(SymEnd);3195}31963197void CodeViewDebug::emitEndSymbolRecord(SymbolKind EndKind) {3198OS.AddComment("Record length");3199OS.emitInt16(2);3200if (OS.isVerboseAsm())3201OS.AddComment("Record kind: " + getSymbolName(EndKind));3202OS.emitInt16(uint16_t(EndKind)); // Record Kind3203}32043205void CodeViewDebug::emitDebugInfoForUDTs(3206const std::vector<std::pair<std::string, const DIType *>> &UDTs) {3207#ifndef NDEBUG3208size_t OriginalSize = UDTs.size();3209#endif3210for (const auto &UDT : UDTs) {3211const DIType *T = UDT.second;3212assert(shouldEmitUdt(T));3213MCSymbol *UDTRecordEnd = beginSymbolRecord(SymbolKind::S_UDT);3214OS.AddComment("Type");3215OS.emitInt32(getCompleteTypeIndex(T).getIndex());3216assert(OriginalSize == UDTs.size() &&3217"getCompleteTypeIndex found new UDTs!");3218emitNullTerminatedSymbolName(OS, UDT.first);3219endSymbolRecord(UDTRecordEnd);3220}3221}32223223void CodeViewDebug::collectGlobalVariableInfo() {3224DenseMap<const DIGlobalVariableExpression *, const GlobalVariable *>3225GlobalMap;3226for (const GlobalVariable &GV : MMI->getModule()->globals()) {3227SmallVector<DIGlobalVariableExpression *, 1> GVEs;3228GV.getDebugInfo(GVEs);3229for (const auto *GVE : GVEs)3230GlobalMap[GVE] = &GV;3231}32323233NamedMDNode *CUs = MMI->getModule()->getNamedMetadata("llvm.dbg.cu");3234for (const MDNode *Node : CUs->operands()) {3235const auto *CU = cast<DICompileUnit>(Node);3236for (const auto *GVE : CU->getGlobalVariables()) {3237const DIGlobalVariable *DIGV = GVE->getVariable();3238const DIExpression *DIE = GVE->getExpression();3239// Don't emit string literals in CodeView, as the only useful parts are3240// generally the filename and line number, which isn't possible to output3241// in CodeView. String literals should be the only unnamed GlobalVariable3242// with debug info.3243if (DIGV->getName().empty()) continue;32443245if ((DIE->getNumElements() == 2) &&3246(DIE->getElement(0) == dwarf::DW_OP_plus_uconst))3247// Record the constant offset for the variable.3248//3249// A Fortran common block uses this idiom to encode the offset3250// of a variable from the common block's starting address.3251CVGlobalVariableOffsets.insert(3252std::make_pair(DIGV, DIE->getElement(1)));32533254// Emit constant global variables in a global symbol section.3255if (GlobalMap.count(GVE) == 0 && DIE->isConstant()) {3256CVGlobalVariable CVGV = {DIGV, DIE};3257GlobalVariables.emplace_back(std::move(CVGV));3258}32593260const auto *GV = GlobalMap.lookup(GVE);3261if (!GV || GV->isDeclarationForLinker())3262continue;32633264DIScope *Scope = DIGV->getScope();3265SmallVector<CVGlobalVariable, 1> *VariableList;3266if (Scope && isa<DILocalScope>(Scope)) {3267// Locate a global variable list for this scope, creating one if3268// necessary.3269auto Insertion = ScopeGlobals.insert(3270{Scope, std::unique_ptr<GlobalVariableList>()});3271if (Insertion.second)3272Insertion.first->second = std::make_unique<GlobalVariableList>();3273VariableList = Insertion.first->second.get();3274} else if (GV->hasComdat())3275// Emit this global variable into a COMDAT section.3276VariableList = &ComdatVariables;3277else3278// Emit this global variable in a single global symbol section.3279VariableList = &GlobalVariables;3280CVGlobalVariable CVGV = {DIGV, GV};3281VariableList->emplace_back(std::move(CVGV));3282}3283}3284}32853286void CodeViewDebug::collectDebugInfoForGlobals() {3287for (const CVGlobalVariable &CVGV : GlobalVariables) {3288const DIGlobalVariable *DIGV = CVGV.DIGV;3289const DIScope *Scope = DIGV->getScope();3290getCompleteTypeIndex(DIGV->getType());3291getFullyQualifiedName(Scope, DIGV->getName());3292}32933294for (const CVGlobalVariable &CVGV : ComdatVariables) {3295const DIGlobalVariable *DIGV = CVGV.DIGV;3296const DIScope *Scope = DIGV->getScope();3297getCompleteTypeIndex(DIGV->getType());3298getFullyQualifiedName(Scope, DIGV->getName());3299}3300}33013302void CodeViewDebug::emitDebugInfoForGlobals() {3303// First, emit all globals that are not in a comdat in a single symbol3304// substream. MSVC doesn't like it if the substream is empty, so only open3305// it if we have at least one global to emit.3306switchToDebugSectionForSymbol(nullptr);3307if (!GlobalVariables.empty() || !StaticConstMembers.empty()) {3308OS.AddComment("Symbol subsection for globals");3309MCSymbol *EndLabel = beginCVSubsection(DebugSubsectionKind::Symbols);3310emitGlobalVariableList(GlobalVariables);3311emitStaticConstMemberList();3312endCVSubsection(EndLabel);3313}33143315// Second, emit each global that is in a comdat into its own .debug$S3316// section along with its own symbol substream.3317for (const CVGlobalVariable &CVGV : ComdatVariables) {3318const GlobalVariable *GV = cast<const GlobalVariable *>(CVGV.GVInfo);3319MCSymbol *GVSym = Asm->getSymbol(GV);3320OS.AddComment("Symbol subsection for " +3321Twine(GlobalValue::dropLLVMManglingEscape(GV->getName())));3322switchToDebugSectionForSymbol(GVSym);3323MCSymbol *EndLabel = beginCVSubsection(DebugSubsectionKind::Symbols);3324// FIXME: emitDebugInfoForGlobal() doesn't handle DIExpressions.3325emitDebugInfoForGlobal(CVGV);3326endCVSubsection(EndLabel);3327}3328}33293330void CodeViewDebug::emitDebugInfoForRetainedTypes() {3331NamedMDNode *CUs = MMI->getModule()->getNamedMetadata("llvm.dbg.cu");3332for (const MDNode *Node : CUs->operands()) {3333for (auto *Ty : cast<DICompileUnit>(Node)->getRetainedTypes()) {3334if (DIType *RT = dyn_cast<DIType>(Ty)) {3335getTypeIndex(RT);3336// FIXME: Add to global/local DTU list.3337}3338}3339}3340}33413342// Emit each global variable in the specified array.3343void CodeViewDebug::emitGlobalVariableList(ArrayRef<CVGlobalVariable> Globals) {3344for (const CVGlobalVariable &CVGV : Globals) {3345// FIXME: emitDebugInfoForGlobal() doesn't handle DIExpressions.3346emitDebugInfoForGlobal(CVGV);3347}3348}33493350void CodeViewDebug::emitConstantSymbolRecord(const DIType *DTy, APSInt &Value,3351const std::string &QualifiedName) {3352MCSymbol *SConstantEnd = beginSymbolRecord(SymbolKind::S_CONSTANT);3353OS.AddComment("Type");3354OS.emitInt32(getTypeIndex(DTy).getIndex());33553356OS.AddComment("Value");33573358// Encoded integers shouldn't need more than 10 bytes.3359uint8_t Data[10];3360BinaryStreamWriter Writer(Data, llvm::endianness::little);3361CodeViewRecordIO IO(Writer);3362cantFail(IO.mapEncodedInteger(Value));3363StringRef SRef((char *)Data, Writer.getOffset());3364OS.emitBinaryData(SRef);33653366OS.AddComment("Name");3367emitNullTerminatedSymbolName(OS, QualifiedName);3368endSymbolRecord(SConstantEnd);3369}33703371void CodeViewDebug::emitStaticConstMemberList() {3372for (const DIDerivedType *DTy : StaticConstMembers) {3373const DIScope *Scope = DTy->getScope();33743375APSInt Value;3376if (const ConstantInt *CI =3377dyn_cast_or_null<ConstantInt>(DTy->getConstant()))3378Value = APSInt(CI->getValue(),3379DebugHandlerBase::isUnsignedDIType(DTy->getBaseType()));3380else if (const ConstantFP *CFP =3381dyn_cast_or_null<ConstantFP>(DTy->getConstant()))3382Value = APSInt(CFP->getValueAPF().bitcastToAPInt(), true);3383else3384llvm_unreachable("cannot emit a constant without a value");33853386emitConstantSymbolRecord(DTy->getBaseType(), Value,3387getFullyQualifiedName(Scope, DTy->getName()));3388}3389}33903391static bool isFloatDIType(const DIType *Ty) {3392if (isa<DICompositeType>(Ty))3393return false;33943395if (auto *DTy = dyn_cast<DIDerivedType>(Ty)) {3396dwarf::Tag T = (dwarf::Tag)Ty->getTag();3397if (T == dwarf::DW_TAG_pointer_type ||3398T == dwarf::DW_TAG_ptr_to_member_type ||3399T == dwarf::DW_TAG_reference_type ||3400T == dwarf::DW_TAG_rvalue_reference_type)3401return false;3402assert(DTy->getBaseType() && "Expected valid base type");3403return isFloatDIType(DTy->getBaseType());3404}34053406auto *BTy = cast<DIBasicType>(Ty);3407return (BTy->getEncoding() == dwarf::DW_ATE_float);3408}34093410void CodeViewDebug::emitDebugInfoForGlobal(const CVGlobalVariable &CVGV) {3411const DIGlobalVariable *DIGV = CVGV.DIGV;34123413const DIScope *Scope = DIGV->getScope();3414// For static data members, get the scope from the declaration.3415if (const auto *MemberDecl = dyn_cast_or_null<DIDerivedType>(3416DIGV->getRawStaticDataMemberDeclaration()))3417Scope = MemberDecl->getScope();3418// For static local variables and Fortran, the scoping portion is elided3419// in its name so that we can reference the variable in the command line3420// of the VS debugger.3421std::string QualifiedName =3422(moduleIsInFortran() || (Scope && isa<DILocalScope>(Scope)))3423? std::string(DIGV->getName())3424: getFullyQualifiedName(Scope, DIGV->getName());34253426if (const GlobalVariable *GV =3427dyn_cast_if_present<const GlobalVariable *>(CVGV.GVInfo)) {3428// DataSym record, see SymbolRecord.h for more info. Thread local data3429// happens to have the same format as global data.3430MCSymbol *GVSym = Asm->getSymbol(GV);3431SymbolKind DataSym = GV->isThreadLocal()3432? (DIGV->isLocalToUnit() ? SymbolKind::S_LTHREAD323433: SymbolKind::S_GTHREAD32)3434: (DIGV->isLocalToUnit() ? SymbolKind::S_LDATA323435: SymbolKind::S_GDATA32);3436MCSymbol *DataEnd = beginSymbolRecord(DataSym);3437OS.AddComment("Type");3438OS.emitInt32(getCompleteTypeIndex(DIGV->getType()).getIndex());3439OS.AddComment("DataOffset");34403441uint64_t Offset = 0;3442if (CVGlobalVariableOffsets.contains(DIGV))3443// Use the offset seen while collecting info on globals.3444Offset = CVGlobalVariableOffsets[DIGV];3445OS.emitCOFFSecRel32(GVSym, Offset);34463447OS.AddComment("Segment");3448OS.emitCOFFSectionIndex(GVSym);3449OS.AddComment("Name");3450const unsigned LengthOfDataRecord = 12;3451emitNullTerminatedSymbolName(OS, QualifiedName, LengthOfDataRecord);3452endSymbolRecord(DataEnd);3453} else {3454const DIExpression *DIE = cast<const DIExpression *>(CVGV.GVInfo);3455assert(DIE->isConstant() &&3456"Global constant variables must contain a constant expression.");34573458// Use unsigned for floats.3459bool isUnsigned = isFloatDIType(DIGV->getType())3460? true3461: DebugHandlerBase::isUnsignedDIType(DIGV->getType());3462APSInt Value(APInt(/*BitWidth=*/64, DIE->getElement(1)), isUnsigned);3463emitConstantSymbolRecord(DIGV->getType(), Value, QualifiedName);3464}3465}34663467void forEachJumpTableBranch(3468const MachineFunction *MF, bool isThumb,3469const std::function<void(const MachineJumpTableInfo &, const MachineInstr &,3470int64_t)> &Callback) {3471auto JTI = MF->getJumpTableInfo();3472if (JTI && !JTI->isEmpty()) {3473#ifndef NDEBUG3474auto UsedJTs = llvm::SmallBitVector(JTI->getJumpTables().size());3475#endif3476for (const auto &MBB : *MF) {3477// Search for indirect branches...3478const auto LastMI = MBB.getFirstTerminator();3479if (LastMI != MBB.end() && LastMI->isIndirectBranch()) {3480if (isThumb) {3481// ... that directly use jump table operands.3482// NOTE: ARM uses pattern matching to lower its BR_JT SDNode to3483// machine instructions, hence inserting a JUMP_TABLE_DEBUG_INFO node3484// interferes with this process *but* the resulting pseudo-instruction3485// uses a Jump Table operand, so extract the jump table index directly3486// from that.3487for (const auto &MO : LastMI->operands()) {3488if (MO.isJTI()) {3489unsigned Index = MO.getIndex();3490#ifndef NDEBUG3491UsedJTs.set(Index);3492#endif3493Callback(*JTI, *LastMI, Index);3494break;3495}3496}3497} else {3498// ... that have jump table debug info.3499// NOTE: The debug info is inserted as a JUMP_TABLE_DEBUG_INFO node3500// when lowering the BR_JT SDNode to an indirect branch.3501for (auto I = MBB.instr_rbegin(), E = MBB.instr_rend(); I != E; ++I) {3502if (I->isJumpTableDebugInfo()) {3503unsigned Index = I->getOperand(0).getImm();3504#ifndef NDEBUG3505UsedJTs.set(Index);3506#endif3507Callback(*JTI, *LastMI, Index);3508break;3509}3510}3511}3512}3513}3514#ifndef NDEBUG3515assert(UsedJTs.all() &&3516"Some of jump tables were not used in a debug info instruction");3517#endif3518}3519}35203521void CodeViewDebug::discoverJumpTableBranches(const MachineFunction *MF,3522bool isThumb) {3523forEachJumpTableBranch(3524MF, isThumb,3525[this](const MachineJumpTableInfo &, const MachineInstr &BranchMI,3526int64_t) { requestLabelBeforeInsn(&BranchMI); });3527}35283529void CodeViewDebug::collectDebugInfoForJumpTables(const MachineFunction *MF,3530bool isThumb) {3531forEachJumpTableBranch(3532MF, isThumb,3533[this, MF](const MachineJumpTableInfo &JTI, const MachineInstr &BranchMI,3534int64_t JumpTableIndex) {3535// For label-difference jump tables, find the base expression.3536// Otherwise the jump table uses an absolute address (so no base3537// is required).3538const MCSymbol *Base;3539uint64_t BaseOffset = 0;3540const MCSymbol *Branch = getLabelBeforeInsn(&BranchMI);3541JumpTableEntrySize EntrySize;3542switch (JTI.getEntryKind()) {3543case MachineJumpTableInfo::EK_Custom32:3544case MachineJumpTableInfo::EK_GPRel32BlockAddress:3545case MachineJumpTableInfo::EK_GPRel64BlockAddress:3546llvm_unreachable(3547"EK_Custom32, EK_GPRel32BlockAddress, and "3548"EK_GPRel64BlockAddress should never be emitted for COFF");3549case MachineJumpTableInfo::EK_BlockAddress:3550// Each entry is an absolute address.3551EntrySize = JumpTableEntrySize::Pointer;3552Base = nullptr;3553break;3554case MachineJumpTableInfo::EK_Inline:3555case MachineJumpTableInfo::EK_LabelDifference32:3556case MachineJumpTableInfo::EK_LabelDifference64:3557// Ask the AsmPrinter.3558std::tie(Base, BaseOffset, Branch, EntrySize) =3559Asm->getCodeViewJumpTableInfo(JumpTableIndex, &BranchMI, Branch);3560break;3561}35623563CurFn->JumpTables.push_back(3564{EntrySize, Base, BaseOffset, Branch,3565MF->getJTISymbol(JumpTableIndex, MMI->getContext()),3566JTI.getJumpTables()[JumpTableIndex].MBBs.size()});3567});3568}35693570void CodeViewDebug::emitDebugInfoForJumpTables(const FunctionInfo &FI) {3571for (auto JumpTable : FI.JumpTables) {3572MCSymbol *JumpTableEnd = beginSymbolRecord(SymbolKind::S_ARMSWITCHTABLE);3573if (JumpTable.Base) {3574OS.AddComment("Base offset");3575OS.emitCOFFSecRel32(JumpTable.Base, JumpTable.BaseOffset);3576OS.AddComment("Base section index");3577OS.emitCOFFSectionIndex(JumpTable.Base);3578} else {3579OS.AddComment("Base offset");3580OS.emitInt32(0);3581OS.AddComment("Base section index");3582OS.emitInt16(0);3583}3584OS.AddComment("Switch type");3585OS.emitInt16(static_cast<uint16_t>(JumpTable.EntrySize));3586OS.AddComment("Branch offset");3587OS.emitCOFFSecRel32(JumpTable.Branch, /*Offset=*/0);3588OS.AddComment("Table offset");3589OS.emitCOFFSecRel32(JumpTable.Table, /*Offset=*/0);3590OS.AddComment("Branch section index");3591OS.emitCOFFSectionIndex(JumpTable.Branch);3592OS.AddComment("Table section index");3593OS.emitCOFFSectionIndex(JumpTable.Table);3594OS.AddComment("Entries count");3595OS.emitInt32(JumpTable.TableSize);3596endSymbolRecord(JumpTableEnd);3597}3598}35993600void CodeViewDebug::emitInlinees(3601const SmallSet<codeview::TypeIndex, 1> &Inlinees) {3602// Divide the list of inlinees into chunks such that each chunk fits within3603// one record.3604constexpr size_t ChunkSize =3605(MaxRecordLength - sizeof(SymbolKind) - sizeof(uint32_t)) /3606sizeof(uint32_t);36073608SmallVector<TypeIndex> SortedInlinees{Inlinees.begin(), Inlinees.end()};3609llvm::sort(SortedInlinees);36103611size_t CurrentIndex = 0;3612while (CurrentIndex < SortedInlinees.size()) {3613auto Symbol = beginSymbolRecord(SymbolKind::S_INLINEES);3614auto CurrentChunkSize =3615std::min(ChunkSize, SortedInlinees.size() - CurrentIndex);3616OS.AddComment("Count");3617OS.emitInt32(CurrentChunkSize);36183619const size_t CurrentChunkEnd = CurrentIndex + CurrentChunkSize;3620for (; CurrentIndex < CurrentChunkEnd; ++CurrentIndex) {3621OS.AddComment("Inlinee");3622OS.emitInt32(SortedInlinees[CurrentIndex].getIndex());3623}3624endSymbolRecord(Symbol);3625}3626}362736283629