1db17bf38SDimitry Andric //===- llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp ----------------------===// 23ca95b02SDimitry Andric // 33ca95b02SDimitry Andric // The LLVM Compiler Infrastructure 43ca95b02SDimitry Andric // 53ca95b02SDimitry Andric // This file is distributed under the University of Illinois Open Source 63ca95b02SDimitry Andric // License. See LICENSE.TXT for details. 73ca95b02SDimitry Andric // 83ca95b02SDimitry Andric //===----------------------------------------------------------------------===// 93ca95b02SDimitry Andric // 103ca95b02SDimitry Andric // This file contains support for writing Microsoft CodeView debug info. 113ca95b02SDimitry Andric // 123ca95b02SDimitry Andric //===----------------------------------------------------------------------===// 133ca95b02SDimitry Andric 143ca95b02SDimitry Andric #include "CodeViewDebug.h" 152cab237bSDimitry Andric #include "DwarfExpression.h" 16db17bf38SDimitry Andric #include "llvm/ADT/APSInt.h" 17db17bf38SDimitry Andric #include "llvm/ADT/ArrayRef.h" 18db17bf38SDimitry Andric #include "llvm/ADT/DenseMap.h" 19db17bf38SDimitry Andric #include "llvm/ADT/DenseSet.h" 20db17bf38SDimitry Andric #include "llvm/ADT/MapVector.h" 21db17bf38SDimitry Andric #include "llvm/ADT/None.h" 22db17bf38SDimitry Andric #include "llvm/ADT/Optional.h" 232cab237bSDimitry Andric #include "llvm/ADT/STLExtras.h" 24db17bf38SDimitry Andric #include "llvm/ADT/SmallString.h" 25db17bf38SDimitry Andric #include "llvm/ADT/SmallVector.h" 26db17bf38SDimitry Andric #include "llvm/ADT/StringRef.h" 273ca95b02SDimitry Andric #include "llvm/ADT/TinyPtrVector.h" 28db17bf38SDimitry Andric #include "llvm/ADT/Triple.h" 29db17bf38SDimitry Andric #include "llvm/ADT/Twine.h" 30db17bf38SDimitry Andric #include "llvm/BinaryFormat/COFF.h" 31db17bf38SDimitry Andric #include "llvm/BinaryFormat/Dwarf.h" 32db17bf38SDimitry Andric #include "llvm/CodeGen/AsmPrinter.h" 33db17bf38SDimitry Andric #include "llvm/CodeGen/LexicalScopes.h" 34db17bf38SDimitry Andric #include "llvm/CodeGen/MachineFunction.h" 35db17bf38SDimitry Andric #include "llvm/CodeGen/MachineInstr.h" 36db17bf38SDimitry Andric #include "llvm/CodeGen/MachineModuleInfo.h" 37db17bf38SDimitry Andric #include "llvm/CodeGen/MachineOperand.h" 382cab237bSDimitry Andric #include "llvm/CodeGen/TargetFrameLowering.h" 392cab237bSDimitry Andric #include "llvm/CodeGen/TargetLoweringObjectFile.h" 402cab237bSDimitry Andric #include "llvm/CodeGen/TargetRegisterInfo.h" 412cab237bSDimitry Andric #include "llvm/CodeGen/TargetSubtargetInfo.h" 42db17bf38SDimitry Andric #include "llvm/Config/llvm-config.h" 433ca95b02SDimitry Andric #include "llvm/DebugInfo/CodeView/CVTypeVisitor.h" 443ca95b02SDimitry Andric #include "llvm/DebugInfo/CodeView/CodeView.h" 452cab237bSDimitry Andric #include "llvm/DebugInfo/CodeView/ContinuationRecordBuilder.h" 4689cb50c9SDimitry Andric #include "llvm/DebugInfo/CodeView/DebugInlineeLinesSubsection.h" 473ca95b02SDimitry Andric #include "llvm/DebugInfo/CodeView/Line.h" 483ca95b02SDimitry Andric #include "llvm/DebugInfo/CodeView/SymbolRecord.h" 49f1a29dd3SDimitry Andric #include "llvm/DebugInfo/CodeView/TypeDumpVisitor.h" 503ca95b02SDimitry Andric #include "llvm/DebugInfo/CodeView/TypeIndex.h" 513ca95b02SDimitry Andric #include "llvm/DebugInfo/CodeView/TypeRecord.h" 52d8866befSDimitry Andric #include "llvm/DebugInfo/CodeView/TypeTableCollection.h" 533ca95b02SDimitry Andric #include "llvm/IR/Constants.h" 54db17bf38SDimitry Andric #include "llvm/IR/DataLayout.h" 55db17bf38SDimitry Andric #include "llvm/IR/DebugInfoMetadata.h" 56db17bf38SDimitry Andric #include "llvm/IR/DebugLoc.h" 57db17bf38SDimitry Andric #include "llvm/IR/Function.h" 58db17bf38SDimitry Andric #include "llvm/IR/GlobalValue.h" 59db17bf38SDimitry Andric #include "llvm/IR/GlobalVariable.h" 60db17bf38SDimitry Andric #include "llvm/IR/Metadata.h" 61db17bf38SDimitry Andric #include "llvm/IR/Module.h" 62d88c1a5aSDimitry Andric #include "llvm/MC/MCAsmInfo.h" 63db17bf38SDimitry Andric #include "llvm/MC/MCContext.h" 643ca95b02SDimitry Andric #include "llvm/MC/MCSectionCOFF.h" 65db17bf38SDimitry Andric #include "llvm/MC/MCStreamer.h" 663ca95b02SDimitry Andric #include "llvm/MC/MCSymbol.h" 677a7e6055SDimitry Andric #include "llvm/Support/BinaryByteStream.h" 687a7e6055SDimitry Andric #include "llvm/Support/BinaryStreamReader.h" 69db17bf38SDimitry Andric #include "llvm/Support/Casting.h" 702cab237bSDimitry Andric #include "llvm/Support/CommandLine.h" 71db17bf38SDimitry Andric #include "llvm/Support/Compiler.h" 72db17bf38SDimitry Andric #include "llvm/Support/Endian.h" 73db17bf38SDimitry Andric #include "llvm/Support/Error.h" 74db17bf38SDimitry Andric #include "llvm/Support/ErrorHandling.h" 752cab237bSDimitry Andric #include "llvm/Support/FormatVariadic.h" 76db17bf38SDimitry Andric #include "llvm/Support/SMLoc.h" 772cab237bSDimitry Andric #include "llvm/Support/ScopedPrinter.h" 78db17bf38SDimitry Andric #include "llvm/Target/TargetMachine.h" 79db17bf38SDimitry Andric #include <algorithm> 80db17bf38SDimitry Andric #include <cassert> 81db17bf38SDimitry Andric #include <cctype> 82db17bf38SDimitry Andric #include <cstddef> 83db17bf38SDimitry Andric #include <cstdint> 84db17bf38SDimitry Andric #include <iterator> 85db17bf38SDimitry Andric #include <limits> 86db17bf38SDimitry Andric #include <string> 87db17bf38SDimitry Andric #include <utility> 88db17bf38SDimitry Andric #include <vector> 893ca95b02SDimitry Andric 903ca95b02SDimitry Andric using namespace llvm; 913ca95b02SDimitry Andric using namespace llvm::codeview; 923ca95b02SDimitry Andric 932cab237bSDimitry Andric static cl::opt<bool> EmitDebugGlobalHashes("emit-codeview-ghash-section", 942cab237bSDimitry Andric cl::ReallyHidden, cl::init(false)); 952cab237bSDimitry Andric 963ca95b02SDimitry Andric CodeViewDebug::CodeViewDebug(AsmPrinter *AP) 97db17bf38SDimitry Andric : DebugHandlerBase(AP), OS(*Asm->OutStreamer), TypeTable(Allocator) { 983ca95b02SDimitry Andric // If module doesn't have named metadata anchors or COFF debug section 993ca95b02SDimitry Andric // is not available, skip any debug info related stuff. 1003ca95b02SDimitry Andric if (!MMI->getModule()->getNamedMetadata("llvm.dbg.cu") || 1013ca95b02SDimitry Andric !AP->getObjFileLowering().getCOFFDebugSymbolsSection()) { 1023ca95b02SDimitry Andric Asm = nullptr; 1033ca95b02SDimitry Andric return; 1043ca95b02SDimitry Andric } 1053ca95b02SDimitry Andric 1063ca95b02SDimitry Andric // Tell MMI that we have debug info. 1073ca95b02SDimitry Andric MMI->setDebugInfoAvailability(true); 1083ca95b02SDimitry Andric } 1093ca95b02SDimitry Andric 1103ca95b02SDimitry Andric StringRef CodeViewDebug::getFullFilepath(const DIFile *File) { 1113ca95b02SDimitry Andric std::string &Filepath = FileToFilepathMap[File]; 1123ca95b02SDimitry Andric if (!Filepath.empty()) 1133ca95b02SDimitry Andric return Filepath; 1143ca95b02SDimitry Andric 1153ca95b02SDimitry Andric StringRef Dir = File->getDirectory(), Filename = File->getFilename(); 1163ca95b02SDimitry Andric 1173ca95b02SDimitry Andric // Clang emits directory and relative filename info into the IR, but CodeView 1183ca95b02SDimitry Andric // operates on full paths. We could change Clang to emit full paths too, but 1193ca95b02SDimitry Andric // that would increase the IR size and probably not needed for other users. 1203ca95b02SDimitry Andric // For now, just concatenate and canonicalize the path here. 1213ca95b02SDimitry Andric if (Filename.find(':') == 1) 1223ca95b02SDimitry Andric Filepath = Filename; 1233ca95b02SDimitry Andric else 1243ca95b02SDimitry Andric Filepath = (Dir + "\\" + Filename).str(); 1253ca95b02SDimitry Andric 1263ca95b02SDimitry Andric // Canonicalize the path. We have to do it textually because we may no longer 1273ca95b02SDimitry Andric // have access the file in the filesystem. 1283ca95b02SDimitry Andric // First, replace all slashes with backslashes. 1293ca95b02SDimitry Andric std::replace(Filepath.begin(), Filepath.end(), '/', '\\'); 1303ca95b02SDimitry Andric 1313ca95b02SDimitry Andric // Remove all "\.\" with "\". 1323ca95b02SDimitry Andric size_t Cursor = 0; 1333ca95b02SDimitry Andric while ((Cursor = Filepath.find("\\.\\", Cursor)) != std::string::npos) 1343ca95b02SDimitry Andric Filepath.erase(Cursor, 2); 1353ca95b02SDimitry Andric 1363ca95b02SDimitry Andric // Replace all "\XXX\..\" with "\". Don't try too hard though as the original 1373ca95b02SDimitry Andric // path should be well-formatted, e.g. start with a drive letter, etc. 1383ca95b02SDimitry Andric Cursor = 0; 1393ca95b02SDimitry Andric while ((Cursor = Filepath.find("\\..\\", Cursor)) != std::string::npos) { 1403ca95b02SDimitry Andric // Something's wrong if the path starts with "\..\", abort. 1413ca95b02SDimitry Andric if (Cursor == 0) 1423ca95b02SDimitry Andric break; 1433ca95b02SDimitry Andric 1443ca95b02SDimitry Andric size_t PrevSlash = Filepath.rfind('\\', Cursor - 1); 1453ca95b02SDimitry Andric if (PrevSlash == std::string::npos) 1463ca95b02SDimitry Andric // Something's wrong, abort. 1473ca95b02SDimitry Andric break; 1483ca95b02SDimitry Andric 1493ca95b02SDimitry Andric Filepath.erase(PrevSlash, Cursor + 3 - PrevSlash); 1503ca95b02SDimitry Andric // The next ".." might be following the one we've just erased. 1513ca95b02SDimitry Andric Cursor = PrevSlash; 1523ca95b02SDimitry Andric } 1533ca95b02SDimitry Andric 1543ca95b02SDimitry Andric // Remove all duplicate backslashes. 1553ca95b02SDimitry Andric Cursor = 0; 1563ca95b02SDimitry Andric while ((Cursor = Filepath.find("\\\\", Cursor)) != std::string::npos) 1573ca95b02SDimitry Andric Filepath.erase(Cursor, 1); 1583ca95b02SDimitry Andric 1593ca95b02SDimitry Andric return Filepath; 1603ca95b02SDimitry Andric } 1613ca95b02SDimitry Andric 1623ca95b02SDimitry Andric unsigned CodeViewDebug::maybeRecordFile(const DIFile *F) { 1632cab237bSDimitry Andric StringRef FullPath = getFullFilepath(F); 1643ca95b02SDimitry Andric unsigned NextId = FileIdMap.size() + 1; 1652cab237bSDimitry Andric auto Insertion = FileIdMap.insert(std::make_pair(FullPath, NextId)); 1663ca95b02SDimitry Andric if (Insertion.second) { 1673ca95b02SDimitry Andric // We have to compute the full filepath and emit a .cv_file directive. 1682cab237bSDimitry Andric std::string Checksum = fromHex(F->getChecksum()); 1692cab237bSDimitry Andric void *CKMem = OS.getContext().allocate(Checksum.size(), 1); 1702cab237bSDimitry Andric memcpy(CKMem, Checksum.data(), Checksum.size()); 1712cab237bSDimitry Andric ArrayRef<uint8_t> ChecksumAsBytes(reinterpret_cast<const uint8_t *>(CKMem), 1722cab237bSDimitry Andric Checksum.size()); 1732cab237bSDimitry Andric DIFile::ChecksumKind ChecksumKind = F->getChecksumKind(); 1742cab237bSDimitry Andric bool Success = OS.EmitCVFileDirective(NextId, FullPath, ChecksumAsBytes, 1752cab237bSDimitry Andric static_cast<unsigned>(ChecksumKind)); 176d88c1a5aSDimitry Andric (void)Success; 177d88c1a5aSDimitry Andric assert(Success && ".cv_file directive failed"); 1783ca95b02SDimitry Andric } 1793ca95b02SDimitry Andric return Insertion.first->second; 1803ca95b02SDimitry Andric } 1813ca95b02SDimitry Andric 1823ca95b02SDimitry Andric CodeViewDebug::InlineSite & 1833ca95b02SDimitry Andric CodeViewDebug::getInlineSite(const DILocation *InlinedAt, 1843ca95b02SDimitry Andric const DISubprogram *Inlinee) { 1853ca95b02SDimitry Andric auto SiteInsertion = CurFn->InlineSites.insert({InlinedAt, InlineSite()}); 1863ca95b02SDimitry Andric InlineSite *Site = &SiteInsertion.first->second; 1873ca95b02SDimitry Andric if (SiteInsertion.second) { 188d88c1a5aSDimitry Andric unsigned ParentFuncId = CurFn->FuncId; 189d88c1a5aSDimitry Andric if (const DILocation *OuterIA = InlinedAt->getInlinedAt()) 190d88c1a5aSDimitry Andric ParentFuncId = 191d88c1a5aSDimitry Andric getInlineSite(OuterIA, InlinedAt->getScope()->getSubprogram()) 192d88c1a5aSDimitry Andric .SiteFuncId; 193d88c1a5aSDimitry Andric 1943ca95b02SDimitry Andric Site->SiteFuncId = NextFuncId++; 195d88c1a5aSDimitry Andric OS.EmitCVInlineSiteIdDirective( 196d88c1a5aSDimitry Andric Site->SiteFuncId, ParentFuncId, maybeRecordFile(InlinedAt->getFile()), 197d88c1a5aSDimitry Andric InlinedAt->getLine(), InlinedAt->getColumn(), SMLoc()); 1983ca95b02SDimitry Andric Site->Inlinee = Inlinee; 1993ca95b02SDimitry Andric InlinedSubprograms.insert(Inlinee); 2003ca95b02SDimitry Andric getFuncIdForSubprogram(Inlinee); 2013ca95b02SDimitry Andric } 2023ca95b02SDimitry Andric return *Site; 2033ca95b02SDimitry Andric } 2043ca95b02SDimitry Andric 2053ca95b02SDimitry Andric static StringRef getPrettyScopeName(const DIScope *Scope) { 2063ca95b02SDimitry Andric StringRef ScopeName = Scope->getName(); 2073ca95b02SDimitry Andric if (!ScopeName.empty()) 2083ca95b02SDimitry Andric return ScopeName; 2093ca95b02SDimitry Andric 2103ca95b02SDimitry Andric switch (Scope->getTag()) { 2113ca95b02SDimitry Andric case dwarf::DW_TAG_enumeration_type: 2123ca95b02SDimitry Andric case dwarf::DW_TAG_class_type: 2133ca95b02SDimitry Andric case dwarf::DW_TAG_structure_type: 2143ca95b02SDimitry Andric case dwarf::DW_TAG_union_type: 2153ca95b02SDimitry Andric return "<unnamed-tag>"; 2163ca95b02SDimitry Andric case dwarf::DW_TAG_namespace: 2173ca95b02SDimitry Andric return "`anonymous namespace'"; 2183ca95b02SDimitry Andric } 2193ca95b02SDimitry Andric 2203ca95b02SDimitry Andric return StringRef(); 2213ca95b02SDimitry Andric } 2223ca95b02SDimitry Andric 2233ca95b02SDimitry Andric static const DISubprogram *getQualifiedNameComponents( 2243ca95b02SDimitry Andric const DIScope *Scope, SmallVectorImpl<StringRef> &QualifiedNameComponents) { 2253ca95b02SDimitry Andric const DISubprogram *ClosestSubprogram = nullptr; 2263ca95b02SDimitry Andric while (Scope != nullptr) { 2273ca95b02SDimitry Andric if (ClosestSubprogram == nullptr) 2283ca95b02SDimitry Andric ClosestSubprogram = dyn_cast<DISubprogram>(Scope); 2293ca95b02SDimitry Andric StringRef ScopeName = getPrettyScopeName(Scope); 2303ca95b02SDimitry Andric if (!ScopeName.empty()) 2313ca95b02SDimitry Andric QualifiedNameComponents.push_back(ScopeName); 2323ca95b02SDimitry Andric Scope = Scope->getScope().resolve(); 2333ca95b02SDimitry Andric } 2343ca95b02SDimitry Andric return ClosestSubprogram; 2353ca95b02SDimitry Andric } 2363ca95b02SDimitry Andric 2373ca95b02SDimitry Andric static std::string getQualifiedName(ArrayRef<StringRef> QualifiedNameComponents, 2383ca95b02SDimitry Andric StringRef TypeName) { 2393ca95b02SDimitry Andric std::string FullyQualifiedName; 240db17bf38SDimitry Andric for (StringRef QualifiedNameComponent : 241db17bf38SDimitry Andric llvm::reverse(QualifiedNameComponents)) { 2423ca95b02SDimitry Andric FullyQualifiedName.append(QualifiedNameComponent); 2433ca95b02SDimitry Andric FullyQualifiedName.append("::"); 2443ca95b02SDimitry Andric } 2453ca95b02SDimitry Andric FullyQualifiedName.append(TypeName); 2463ca95b02SDimitry Andric return FullyQualifiedName; 2473ca95b02SDimitry Andric } 2483ca95b02SDimitry Andric 2493ca95b02SDimitry Andric static std::string getFullyQualifiedName(const DIScope *Scope, StringRef Name) { 2503ca95b02SDimitry Andric SmallVector<StringRef, 5> QualifiedNameComponents; 2513ca95b02SDimitry Andric getQualifiedNameComponents(Scope, QualifiedNameComponents); 2523ca95b02SDimitry Andric return getQualifiedName(QualifiedNameComponents, Name); 2533ca95b02SDimitry Andric } 2543ca95b02SDimitry Andric 2553ca95b02SDimitry Andric struct CodeViewDebug::TypeLoweringScope { 2563ca95b02SDimitry Andric TypeLoweringScope(CodeViewDebug &CVD) : CVD(CVD) { ++CVD.TypeEmissionLevel; } 2573ca95b02SDimitry Andric ~TypeLoweringScope() { 2583ca95b02SDimitry Andric // Don't decrement TypeEmissionLevel until after emitting deferred types, so 2593ca95b02SDimitry Andric // inner TypeLoweringScopes don't attempt to emit deferred types. 2603ca95b02SDimitry Andric if (CVD.TypeEmissionLevel == 1) 2613ca95b02SDimitry Andric CVD.emitDeferredCompleteTypes(); 2623ca95b02SDimitry Andric --CVD.TypeEmissionLevel; 2633ca95b02SDimitry Andric } 2643ca95b02SDimitry Andric CodeViewDebug &CVD; 2653ca95b02SDimitry Andric }; 2663ca95b02SDimitry Andric 2673ca95b02SDimitry Andric static std::string getFullyQualifiedName(const DIScope *Ty) { 2683ca95b02SDimitry Andric const DIScope *Scope = Ty->getScope().resolve(); 2693ca95b02SDimitry Andric return getFullyQualifiedName(Scope, getPrettyScopeName(Ty)); 2703ca95b02SDimitry Andric } 2713ca95b02SDimitry Andric 2723ca95b02SDimitry Andric TypeIndex CodeViewDebug::getScopeIndex(const DIScope *Scope) { 2733ca95b02SDimitry Andric // No scope means global scope and that uses the zero index. 2743ca95b02SDimitry Andric if (!Scope || isa<DIFile>(Scope)) 2753ca95b02SDimitry Andric return TypeIndex(); 2763ca95b02SDimitry Andric 2773ca95b02SDimitry Andric assert(!isa<DIType>(Scope) && "shouldn't make a namespace scope for a type"); 2783ca95b02SDimitry Andric 2793ca95b02SDimitry Andric // Check if we've already translated this scope. 2803ca95b02SDimitry Andric auto I = TypeIndices.find({Scope, nullptr}); 2813ca95b02SDimitry Andric if (I != TypeIndices.end()) 2823ca95b02SDimitry Andric return I->second; 2833ca95b02SDimitry Andric 2843ca95b02SDimitry Andric // Build the fully qualified name of the scope. 2853ca95b02SDimitry Andric std::string ScopeName = getFullyQualifiedName(Scope); 286d88c1a5aSDimitry Andric StringIdRecord SID(TypeIndex(), ScopeName); 2872cab237bSDimitry Andric auto TI = TypeTable.writeLeafType(SID); 2883ca95b02SDimitry Andric return recordTypeIndexForDINode(Scope, TI); 2893ca95b02SDimitry Andric } 2903ca95b02SDimitry Andric 2913ca95b02SDimitry Andric TypeIndex CodeViewDebug::getFuncIdForSubprogram(const DISubprogram *SP) { 2926c4bc1bdSDimitry Andric assert(SP); 2933ca95b02SDimitry Andric 2943ca95b02SDimitry Andric // Check if we've already translated this subprogram. 2953ca95b02SDimitry Andric auto I = TypeIndices.find({SP, nullptr}); 2963ca95b02SDimitry Andric if (I != TypeIndices.end()) 2973ca95b02SDimitry Andric return I->second; 2983ca95b02SDimitry Andric 2993ca95b02SDimitry Andric // The display name includes function template arguments. Drop them to match 3003ca95b02SDimitry Andric // MSVC. 301f37b6182SDimitry Andric StringRef DisplayName = SP->getName().split('<').first; 3023ca95b02SDimitry Andric 3033ca95b02SDimitry Andric const DIScope *Scope = SP->getScope().resolve(); 3043ca95b02SDimitry Andric TypeIndex TI; 3053ca95b02SDimitry Andric if (const auto *Class = dyn_cast_or_null<DICompositeType>(Scope)) { 3063ca95b02SDimitry Andric // If the scope is a DICompositeType, then this must be a method. Member 3073ca95b02SDimitry Andric // function types take some special handling, and require access to the 3083ca95b02SDimitry Andric // subprogram. 3093ca95b02SDimitry Andric TypeIndex ClassType = getTypeIndex(Class); 3103ca95b02SDimitry Andric MemberFuncIdRecord MFuncId(ClassType, getMemberFunctionType(SP, Class), 3113ca95b02SDimitry Andric DisplayName); 3122cab237bSDimitry Andric TI = TypeTable.writeLeafType(MFuncId); 3133ca95b02SDimitry Andric } else { 3143ca95b02SDimitry Andric // Otherwise, this must be a free function. 3153ca95b02SDimitry Andric TypeIndex ParentScope = getScopeIndex(Scope); 3163ca95b02SDimitry Andric FuncIdRecord FuncId(ParentScope, getTypeIndex(SP->getType()), DisplayName); 3172cab237bSDimitry Andric TI = TypeTable.writeLeafType(FuncId); 3183ca95b02SDimitry Andric } 3193ca95b02SDimitry Andric 3203ca95b02SDimitry Andric return recordTypeIndexForDINode(SP, TI); 3213ca95b02SDimitry Andric } 3223ca95b02SDimitry Andric 3233ca95b02SDimitry Andric TypeIndex CodeViewDebug::getMemberFunctionType(const DISubprogram *SP, 3243ca95b02SDimitry Andric const DICompositeType *Class) { 3253ca95b02SDimitry Andric // Always use the method declaration as the key for the function type. The 3263ca95b02SDimitry Andric // method declaration contains the this adjustment. 3273ca95b02SDimitry Andric if (SP->getDeclaration()) 3283ca95b02SDimitry Andric SP = SP->getDeclaration(); 3293ca95b02SDimitry Andric assert(!SP->getDeclaration() && "should use declaration as key"); 3303ca95b02SDimitry Andric 3313ca95b02SDimitry Andric // Key the MemberFunctionRecord into the map as {SP, Class}. It won't collide 3323ca95b02SDimitry Andric // with the MemberFuncIdRecord, which is keyed in as {SP, nullptr}. 3333ca95b02SDimitry Andric auto I = TypeIndices.find({SP, Class}); 3343ca95b02SDimitry Andric if (I != TypeIndices.end()) 3353ca95b02SDimitry Andric return I->second; 3363ca95b02SDimitry Andric 3373ca95b02SDimitry Andric // Make sure complete type info for the class is emitted *after* the member 3383ca95b02SDimitry Andric // function type, as the complete class type is likely to reference this 3393ca95b02SDimitry Andric // member function type. 3403ca95b02SDimitry Andric TypeLoweringScope S(*this); 3412cab237bSDimitry Andric const bool IsStaticMethod = (SP->getFlags() & DINode::FlagStaticMember) != 0; 3422cab237bSDimitry Andric TypeIndex TI = lowerTypeMemberFunction( 3432cab237bSDimitry Andric SP->getType(), Class, SP->getThisAdjustment(), IsStaticMethod); 3443ca95b02SDimitry Andric return recordTypeIndexForDINode(SP, TI, Class); 3453ca95b02SDimitry Andric } 3463ca95b02SDimitry Andric 3473ca95b02SDimitry Andric TypeIndex CodeViewDebug::recordTypeIndexForDINode(const DINode *Node, 3483ca95b02SDimitry Andric TypeIndex TI, 3493ca95b02SDimitry Andric const DIType *ClassTy) { 3503ca95b02SDimitry Andric auto InsertResult = TypeIndices.insert({{Node, ClassTy}, TI}); 3513ca95b02SDimitry Andric (void)InsertResult; 3523ca95b02SDimitry Andric assert(InsertResult.second && "DINode was already assigned a type index"); 3533ca95b02SDimitry Andric return TI; 3543ca95b02SDimitry Andric } 3553ca95b02SDimitry Andric 3563ca95b02SDimitry Andric unsigned CodeViewDebug::getPointerSizeInBytes() { 3573ca95b02SDimitry Andric return MMI->getModule()->getDataLayout().getPointerSizeInBits() / 8; 3583ca95b02SDimitry Andric } 3593ca95b02SDimitry Andric 3603ca95b02SDimitry Andric void CodeViewDebug::recordLocalVariable(LocalVariable &&Var, 3613ca95b02SDimitry Andric const DILocation *InlinedAt) { 3623ca95b02SDimitry Andric if (InlinedAt) { 3633ca95b02SDimitry Andric // This variable was inlined. Associate it with the InlineSite. 3643ca95b02SDimitry Andric const DISubprogram *Inlinee = Var.DIVar->getScope()->getSubprogram(); 3653ca95b02SDimitry Andric InlineSite &Site = getInlineSite(InlinedAt, Inlinee); 3663ca95b02SDimitry Andric Site.InlinedLocals.emplace_back(Var); 3673ca95b02SDimitry Andric } else { 3683ca95b02SDimitry Andric // This variable goes in the main ProcSym. 3693ca95b02SDimitry Andric CurFn->Locals.emplace_back(Var); 3703ca95b02SDimitry Andric } 3713ca95b02SDimitry Andric } 3723ca95b02SDimitry Andric 3733ca95b02SDimitry Andric static void addLocIfNotPresent(SmallVectorImpl<const DILocation *> &Locs, 3743ca95b02SDimitry Andric const DILocation *Loc) { 3753ca95b02SDimitry Andric auto B = Locs.begin(), E = Locs.end(); 3763ca95b02SDimitry Andric if (std::find(B, E, Loc) == E) 3773ca95b02SDimitry Andric Locs.push_back(Loc); 3783ca95b02SDimitry Andric } 3793ca95b02SDimitry Andric 3803ca95b02SDimitry Andric void CodeViewDebug::maybeRecordLocation(const DebugLoc &DL, 3813ca95b02SDimitry Andric const MachineFunction *MF) { 3823ca95b02SDimitry Andric // Skip this instruction if it has the same location as the previous one. 383a580b014SDimitry Andric if (!DL || DL == PrevInstLoc) 3843ca95b02SDimitry Andric return; 3853ca95b02SDimitry Andric 3863ca95b02SDimitry Andric const DIScope *Scope = DL.get()->getScope(); 3873ca95b02SDimitry Andric if (!Scope) 3883ca95b02SDimitry Andric return; 3893ca95b02SDimitry Andric 3903ca95b02SDimitry Andric // Skip this line if it is longer than the maximum we can record. 3913ca95b02SDimitry Andric LineInfo LI(DL.getLine(), DL.getLine(), /*IsStatement=*/true); 3923ca95b02SDimitry Andric if (LI.getStartLine() != DL.getLine() || LI.isAlwaysStepInto() || 3933ca95b02SDimitry Andric LI.isNeverStepInto()) 3943ca95b02SDimitry Andric return; 3953ca95b02SDimitry Andric 3963ca95b02SDimitry Andric ColumnInfo CI(DL.getCol(), /*EndColumn=*/0); 3973ca95b02SDimitry Andric if (CI.getStartColumn() != DL.getCol()) 3983ca95b02SDimitry Andric return; 3993ca95b02SDimitry Andric 4003ca95b02SDimitry Andric if (!CurFn->HaveLineInfo) 4013ca95b02SDimitry Andric CurFn->HaveLineInfo = true; 4023ca95b02SDimitry Andric unsigned FileId = 0; 403a580b014SDimitry Andric if (PrevInstLoc.get() && PrevInstLoc->getFile() == DL->getFile()) 4043ca95b02SDimitry Andric FileId = CurFn->LastFileId; 4053ca95b02SDimitry Andric else 4063ca95b02SDimitry Andric FileId = CurFn->LastFileId = maybeRecordFile(DL->getFile()); 407a580b014SDimitry Andric PrevInstLoc = DL; 4083ca95b02SDimitry Andric 4093ca95b02SDimitry Andric unsigned FuncId = CurFn->FuncId; 4103ca95b02SDimitry Andric if (const DILocation *SiteLoc = DL->getInlinedAt()) { 4113ca95b02SDimitry Andric const DILocation *Loc = DL.get(); 4123ca95b02SDimitry Andric 4133ca95b02SDimitry Andric // If this location was actually inlined from somewhere else, give it the ID 4143ca95b02SDimitry Andric // of the inline call site. 4153ca95b02SDimitry Andric FuncId = 4163ca95b02SDimitry Andric getInlineSite(SiteLoc, Loc->getScope()->getSubprogram()).SiteFuncId; 4173ca95b02SDimitry Andric 4183ca95b02SDimitry Andric // Ensure we have links in the tree of inline call sites. 4193ca95b02SDimitry Andric bool FirstLoc = true; 4203ca95b02SDimitry Andric while ((SiteLoc = Loc->getInlinedAt())) { 4213ca95b02SDimitry Andric InlineSite &Site = 4223ca95b02SDimitry Andric getInlineSite(SiteLoc, Loc->getScope()->getSubprogram()); 4233ca95b02SDimitry Andric if (!FirstLoc) 4243ca95b02SDimitry Andric addLocIfNotPresent(Site.ChildSites, Loc); 4253ca95b02SDimitry Andric FirstLoc = false; 4263ca95b02SDimitry Andric Loc = SiteLoc; 4273ca95b02SDimitry Andric } 4283ca95b02SDimitry Andric addLocIfNotPresent(CurFn->ChildSites, Loc); 4293ca95b02SDimitry Andric } 4303ca95b02SDimitry Andric 4313ca95b02SDimitry Andric OS.EmitCVLocDirective(FuncId, FileId, DL.getLine(), DL.getCol(), 432d88c1a5aSDimitry Andric /*PrologueEnd=*/false, /*IsStmt=*/false, 433d88c1a5aSDimitry Andric DL->getFilename(), SMLoc()); 4343ca95b02SDimitry Andric } 4353ca95b02SDimitry Andric 4363ca95b02SDimitry Andric void CodeViewDebug::emitCodeViewMagicVersion() { 4373ca95b02SDimitry Andric OS.EmitValueToAlignment(4); 4383ca95b02SDimitry Andric OS.AddComment("Debug section magic"); 4393ca95b02SDimitry Andric OS.EmitIntValue(COFF::DEBUG_SECTION_MAGIC, 4); 4403ca95b02SDimitry Andric } 4413ca95b02SDimitry Andric 4423ca95b02SDimitry Andric void CodeViewDebug::endModule() { 4433ca95b02SDimitry Andric if (!Asm || !MMI->hasDebugInfo()) 4443ca95b02SDimitry Andric return; 4453ca95b02SDimitry Andric 4463ca95b02SDimitry Andric assert(Asm != nullptr); 4473ca95b02SDimitry Andric 4483ca95b02SDimitry Andric // The COFF .debug$S section consists of several subsections, each starting 4493ca95b02SDimitry Andric // with a 4-byte control code (e.g. 0xF1, 0xF2, etc) and then a 4-byte length 4503ca95b02SDimitry Andric // of the payload followed by the payload itself. The subsections are 4-byte 4513ca95b02SDimitry Andric // aligned. 4523ca95b02SDimitry Andric 4533ca95b02SDimitry Andric // Use the generic .debug$S section, and make a subsection for all the inlined 4543ca95b02SDimitry Andric // subprograms. 4553ca95b02SDimitry Andric switchToDebugSectionForSymbol(nullptr); 456d88c1a5aSDimitry Andric 45789cb50c9SDimitry Andric MCSymbol *CompilerInfo = beginCVSubsection(DebugSubsectionKind::Symbols); 458d88c1a5aSDimitry Andric emitCompilerInformation(); 459d88c1a5aSDimitry Andric endCVSubsection(CompilerInfo); 460d88c1a5aSDimitry Andric 4613ca95b02SDimitry Andric emitInlineeLinesSubsection(); 4623ca95b02SDimitry Andric 4633ca95b02SDimitry Andric // Emit per-function debug information. 4643ca95b02SDimitry Andric for (auto &P : FnDebugInfo) 4653ca95b02SDimitry Andric if (!P.first->isDeclarationForLinker()) 4663ca95b02SDimitry Andric emitDebugInfoForFunction(P.first, P.second); 4673ca95b02SDimitry Andric 4683ca95b02SDimitry Andric // Emit global variable debug information. 4693ca95b02SDimitry Andric setCurrentSubprogram(nullptr); 4703ca95b02SDimitry Andric emitDebugInfoForGlobals(); 4713ca95b02SDimitry Andric 4723ca95b02SDimitry Andric // Emit retained types. 4733ca95b02SDimitry Andric emitDebugInfoForRetainedTypes(); 4743ca95b02SDimitry Andric 4753ca95b02SDimitry Andric // Switch back to the generic .debug$S section after potentially processing 4763ca95b02SDimitry Andric // comdat symbol sections. 4773ca95b02SDimitry Andric switchToDebugSectionForSymbol(nullptr); 4783ca95b02SDimitry Andric 4793ca95b02SDimitry Andric // Emit UDT records for any types used by global variables. 4803ca95b02SDimitry Andric if (!GlobalUDTs.empty()) { 48189cb50c9SDimitry Andric MCSymbol *SymbolsEnd = beginCVSubsection(DebugSubsectionKind::Symbols); 4823ca95b02SDimitry Andric emitDebugInfoForUDTs(GlobalUDTs); 4833ca95b02SDimitry Andric endCVSubsection(SymbolsEnd); 4843ca95b02SDimitry Andric } 4853ca95b02SDimitry Andric 4863ca95b02SDimitry Andric // This subsection holds a file index to offset in string table table. 4873ca95b02SDimitry Andric OS.AddComment("File index to string table offset subsection"); 4883ca95b02SDimitry Andric OS.EmitCVFileChecksumsDirective(); 4893ca95b02SDimitry Andric 4903ca95b02SDimitry Andric // This subsection holds the string table. 4913ca95b02SDimitry Andric OS.AddComment("String table"); 4923ca95b02SDimitry Andric OS.EmitCVStringTableDirective(); 4933ca95b02SDimitry Andric 4942cab237bSDimitry Andric // Emit type information and hashes last, so that any types we translate while 4952cab237bSDimitry Andric // emitting function info are included. 4963ca95b02SDimitry Andric emitTypeInformation(); 4973ca95b02SDimitry Andric 4982cab237bSDimitry Andric if (EmitDebugGlobalHashes) 4992cab237bSDimitry Andric emitTypeGlobalHashes(); 5002cab237bSDimitry Andric 5013ca95b02SDimitry Andric clear(); 5023ca95b02SDimitry Andric } 5033ca95b02SDimitry Andric 5043ca95b02SDimitry Andric static void emitNullTerminatedSymbolName(MCStreamer &OS, StringRef S) { 505d88c1a5aSDimitry Andric // The maximum CV record length is 0xFF00. Most of the strings we emit appear 506d88c1a5aSDimitry Andric // after a fixed length portion of the record. The fixed length portion should 507d88c1a5aSDimitry Andric // always be less than 0xF00 (3840) bytes, so truncate the string so that the 508d88c1a5aSDimitry Andric // overall record size is less than the maximum allowed. 509d88c1a5aSDimitry Andric unsigned MaxFixedRecordLength = 0xF00; 510d88c1a5aSDimitry Andric SmallString<32> NullTerminatedString( 511d88c1a5aSDimitry Andric S.take_front(MaxRecordLength - MaxFixedRecordLength - 1)); 5123ca95b02SDimitry Andric NullTerminatedString.push_back('\0'); 5133ca95b02SDimitry Andric OS.EmitBytes(NullTerminatedString); 5143ca95b02SDimitry Andric } 5153ca95b02SDimitry Andric 5163ca95b02SDimitry Andric void CodeViewDebug::emitTypeInformation() { 5173ca95b02SDimitry Andric if (TypeTable.empty()) 5183ca95b02SDimitry Andric return; 5193ca95b02SDimitry Andric 5203ca95b02SDimitry Andric // Start the .debug$T section with 0x4. 5213ca95b02SDimitry Andric OS.SwitchSection(Asm->getObjFileLowering().getCOFFDebugTypesSection()); 5223ca95b02SDimitry Andric emitCodeViewMagicVersion(); 5233ca95b02SDimitry Andric 5243ca95b02SDimitry Andric SmallString<8> CommentPrefix; 5253ca95b02SDimitry Andric if (OS.isVerboseAsm()) { 5263ca95b02SDimitry Andric CommentPrefix += '\t'; 5273ca95b02SDimitry Andric CommentPrefix += Asm->MAI->getCommentString(); 5283ca95b02SDimitry Andric CommentPrefix += ' '; 5293ca95b02SDimitry Andric } 5303ca95b02SDimitry Andric 531d8866befSDimitry Andric TypeTableCollection Table(TypeTable.records()); 532d8866befSDimitry Andric Optional<TypeIndex> B = Table.getFirst(); 533d8866befSDimitry Andric while (B) { 534d8866befSDimitry Andric // This will fail if the record data is invalid. 535d8866befSDimitry Andric CVType Record = Table.getType(*B); 536d8866befSDimitry Andric 5373ca95b02SDimitry Andric if (OS.isVerboseAsm()) { 5383ca95b02SDimitry Andric // Emit a block comment describing the type record for readability. 5393ca95b02SDimitry Andric SmallString<512> CommentBlock; 5403ca95b02SDimitry Andric raw_svector_ostream CommentOS(CommentBlock); 5413ca95b02SDimitry Andric ScopedPrinter SP(CommentOS); 5423ca95b02SDimitry Andric SP.setPrefix(CommentPrefix); 543d8866befSDimitry Andric TypeDumpVisitor TDV(Table, &SP, false); 544d8866befSDimitry Andric 545d8866befSDimitry Andric Error E = codeview::visitTypeRecord(Record, *B, TDV); 5463ca95b02SDimitry Andric if (E) { 5473ca95b02SDimitry Andric logAllUnhandledErrors(std::move(E), errs(), "error: "); 5483ca95b02SDimitry Andric llvm_unreachable("produced malformed type record"); 5493ca95b02SDimitry Andric } 5503ca95b02SDimitry Andric // emitRawComment will insert its own tab and comment string before 5513ca95b02SDimitry Andric // the first line, so strip off our first one. It also prints its own 5523ca95b02SDimitry Andric // newline. 5533ca95b02SDimitry Andric OS.emitRawComment( 5543ca95b02SDimitry Andric CommentOS.str().drop_front(CommentPrefix.size() - 1).rtrim()); 5553ca95b02SDimitry Andric } 556d8866befSDimitry Andric OS.EmitBinaryData(Record.str_data()); 557d8866befSDimitry Andric B = Table.getNext(*B); 5583ca95b02SDimitry Andric } 5593ca95b02SDimitry Andric } 5603ca95b02SDimitry Andric 5612cab237bSDimitry Andric void CodeViewDebug::emitTypeGlobalHashes() { 5622cab237bSDimitry Andric if (TypeTable.empty()) 5632cab237bSDimitry Andric return; 5642cab237bSDimitry Andric 5652cab237bSDimitry Andric // Start the .debug$H section with the version and hash algorithm, currently 5662cab237bSDimitry Andric // hardcoded to version 0, SHA1. 5672cab237bSDimitry Andric OS.SwitchSection(Asm->getObjFileLowering().getCOFFGlobalTypeHashesSection()); 5682cab237bSDimitry Andric 5692cab237bSDimitry Andric OS.EmitValueToAlignment(4); 5702cab237bSDimitry Andric OS.AddComment("Magic"); 5712cab237bSDimitry Andric OS.EmitIntValue(COFF::DEBUG_HASHES_SECTION_MAGIC, 4); 5722cab237bSDimitry Andric OS.AddComment("Section Version"); 5732cab237bSDimitry Andric OS.EmitIntValue(0, 2); 5742cab237bSDimitry Andric OS.AddComment("Hash Algorithm"); 5752cab237bSDimitry Andric OS.EmitIntValue(uint16_t(GlobalTypeHashAlg::SHA1), 2); 5762cab237bSDimitry Andric 5772cab237bSDimitry Andric TypeIndex TI(TypeIndex::FirstNonSimpleIndex); 5782cab237bSDimitry Andric for (const auto &GHR : TypeTable.hashes()) { 5792cab237bSDimitry Andric if (OS.isVerboseAsm()) { 5802cab237bSDimitry Andric // Emit an EOL-comment describing which TypeIndex this hash corresponds 5812cab237bSDimitry Andric // to, as well as the stringified SHA1 hash. 5822cab237bSDimitry Andric SmallString<32> Comment; 5832cab237bSDimitry Andric raw_svector_ostream CommentOS(Comment); 5842cab237bSDimitry Andric CommentOS << formatv("{0:X+} [{1}]", TI.getIndex(), GHR); 5852cab237bSDimitry Andric OS.AddComment(Comment); 5862cab237bSDimitry Andric ++TI; 5872cab237bSDimitry Andric } 5882cab237bSDimitry Andric assert(GHR.Hash.size() % 20 == 0); 5892cab237bSDimitry Andric StringRef S(reinterpret_cast<const char *>(GHR.Hash.data()), 5902cab237bSDimitry Andric GHR.Hash.size()); 5912cab237bSDimitry Andric OS.EmitBinaryData(S); 5922cab237bSDimitry Andric } 5932cab237bSDimitry Andric } 594d88c1a5aSDimitry Andric 595d88c1a5aSDimitry Andric static SourceLanguage MapDWLangToCVLang(unsigned DWLang) { 596d88c1a5aSDimitry Andric switch (DWLang) { 597d88c1a5aSDimitry Andric case dwarf::DW_LANG_C: 598d88c1a5aSDimitry Andric case dwarf::DW_LANG_C89: 599d88c1a5aSDimitry Andric case dwarf::DW_LANG_C99: 600d88c1a5aSDimitry Andric case dwarf::DW_LANG_C11: 601d88c1a5aSDimitry Andric case dwarf::DW_LANG_ObjC: 602d88c1a5aSDimitry Andric return SourceLanguage::C; 603d88c1a5aSDimitry Andric case dwarf::DW_LANG_C_plus_plus: 604d88c1a5aSDimitry Andric case dwarf::DW_LANG_C_plus_plus_03: 605d88c1a5aSDimitry Andric case dwarf::DW_LANG_C_plus_plus_11: 606d88c1a5aSDimitry Andric case dwarf::DW_LANG_C_plus_plus_14: 607d88c1a5aSDimitry Andric return SourceLanguage::Cpp; 608d88c1a5aSDimitry Andric case dwarf::DW_LANG_Fortran77: 609d88c1a5aSDimitry Andric case dwarf::DW_LANG_Fortran90: 610d88c1a5aSDimitry Andric case dwarf::DW_LANG_Fortran03: 611d88c1a5aSDimitry Andric case dwarf::DW_LANG_Fortran08: 612d88c1a5aSDimitry Andric return SourceLanguage::Fortran; 613d88c1a5aSDimitry Andric case dwarf::DW_LANG_Pascal83: 614d88c1a5aSDimitry Andric return SourceLanguage::Pascal; 615d88c1a5aSDimitry Andric case dwarf::DW_LANG_Cobol74: 616d88c1a5aSDimitry Andric case dwarf::DW_LANG_Cobol85: 617d88c1a5aSDimitry Andric return SourceLanguage::Cobol; 618d88c1a5aSDimitry Andric case dwarf::DW_LANG_Java: 619d88c1a5aSDimitry Andric return SourceLanguage::Java; 6202cab237bSDimitry Andric case dwarf::DW_LANG_D: 6212cab237bSDimitry Andric return SourceLanguage::D; 622d88c1a5aSDimitry Andric default: 623d88c1a5aSDimitry Andric // There's no CodeView representation for this language, and CV doesn't 624d88c1a5aSDimitry Andric // have an "unknown" option for the language field, so we'll use MASM, 625d88c1a5aSDimitry Andric // as it's very low level. 626d88c1a5aSDimitry Andric return SourceLanguage::Masm; 627d88c1a5aSDimitry Andric } 628d88c1a5aSDimitry Andric } 629d88c1a5aSDimitry Andric 6302cab237bSDimitry Andric namespace { 631d88c1a5aSDimitry Andric struct Version { 632d88c1a5aSDimitry Andric int Part[4]; 633d88c1a5aSDimitry Andric }; 6342cab237bSDimitry Andric } // end anonymous namespace 635d88c1a5aSDimitry Andric 636d88c1a5aSDimitry Andric // Takes a StringRef like "clang 4.0.0.0 (other nonsense 123)" and parses out 637d88c1a5aSDimitry Andric // the version number. 638d88c1a5aSDimitry Andric static Version parseVersion(StringRef Name) { 639d88c1a5aSDimitry Andric Version V = {{0}}; 640d88c1a5aSDimitry Andric int N = 0; 641d88c1a5aSDimitry Andric for (const char C : Name) { 642d88c1a5aSDimitry Andric if (isdigit(C)) { 643d88c1a5aSDimitry Andric V.Part[N] *= 10; 644d88c1a5aSDimitry Andric V.Part[N] += C - '0'; 645d88c1a5aSDimitry Andric } else if (C == '.') { 646d88c1a5aSDimitry Andric ++N; 647d88c1a5aSDimitry Andric if (N >= 4) 648d88c1a5aSDimitry Andric return V; 649d88c1a5aSDimitry Andric } else if (N > 0) 650d88c1a5aSDimitry Andric return V; 651d88c1a5aSDimitry Andric } 652d88c1a5aSDimitry Andric return V; 653d88c1a5aSDimitry Andric } 654d88c1a5aSDimitry Andric 655d88c1a5aSDimitry Andric static CPUType mapArchToCVCPUType(Triple::ArchType Type) { 656d88c1a5aSDimitry Andric switch (Type) { 657d88c1a5aSDimitry Andric case Triple::ArchType::x86: 658d88c1a5aSDimitry Andric return CPUType::Pentium3; 659d88c1a5aSDimitry Andric case Triple::ArchType::x86_64: 660d88c1a5aSDimitry Andric return CPUType::X64; 661d88c1a5aSDimitry Andric case Triple::ArchType::thumb: 662d88c1a5aSDimitry Andric return CPUType::Thumb; 6632cab237bSDimitry Andric case Triple::ArchType::aarch64: 6642cab237bSDimitry Andric return CPUType::ARM64; 665d88c1a5aSDimitry Andric default: 6662cab237bSDimitry Andric report_fatal_error("target architecture doesn't map to a CodeView CPUType"); 667d88c1a5aSDimitry Andric } 668d88c1a5aSDimitry Andric } 669d88c1a5aSDimitry Andric 670d88c1a5aSDimitry Andric void CodeViewDebug::emitCompilerInformation() { 671d88c1a5aSDimitry Andric MCContext &Context = MMI->getContext(); 672d88c1a5aSDimitry Andric MCSymbol *CompilerBegin = Context.createTempSymbol(), 673d88c1a5aSDimitry Andric *CompilerEnd = Context.createTempSymbol(); 674d88c1a5aSDimitry Andric OS.AddComment("Record length"); 675d88c1a5aSDimitry Andric OS.emitAbsoluteSymbolDiff(CompilerEnd, CompilerBegin, 2); 676d88c1a5aSDimitry Andric OS.EmitLabel(CompilerBegin); 677d88c1a5aSDimitry Andric OS.AddComment("Record kind: S_COMPILE3"); 678d88c1a5aSDimitry Andric OS.EmitIntValue(SymbolKind::S_COMPILE3, 2); 679d88c1a5aSDimitry Andric uint32_t Flags = 0; 680d88c1a5aSDimitry Andric 681d88c1a5aSDimitry Andric NamedMDNode *CUs = MMI->getModule()->getNamedMetadata("llvm.dbg.cu"); 682d88c1a5aSDimitry Andric const MDNode *Node = *CUs->operands().begin(); 683d88c1a5aSDimitry Andric const auto *CU = cast<DICompileUnit>(Node); 684d88c1a5aSDimitry Andric 685d88c1a5aSDimitry Andric // The low byte of the flags indicates the source language. 686d88c1a5aSDimitry Andric Flags = MapDWLangToCVLang(CU->getSourceLanguage()); 687d88c1a5aSDimitry Andric // TODO: Figure out which other flags need to be set. 688d88c1a5aSDimitry Andric 689d88c1a5aSDimitry Andric OS.AddComment("Flags and language"); 690d88c1a5aSDimitry Andric OS.EmitIntValue(Flags, 4); 691d88c1a5aSDimitry Andric 692d88c1a5aSDimitry Andric OS.AddComment("CPUType"); 693d88c1a5aSDimitry Andric CPUType CPU = 694d88c1a5aSDimitry Andric mapArchToCVCPUType(Triple(MMI->getModule()->getTargetTriple()).getArch()); 695d88c1a5aSDimitry Andric OS.EmitIntValue(static_cast<uint64_t>(CPU), 2); 696d88c1a5aSDimitry Andric 697d88c1a5aSDimitry Andric StringRef CompilerVersion = CU->getProducer(); 698d88c1a5aSDimitry Andric Version FrontVer = parseVersion(CompilerVersion); 699d88c1a5aSDimitry Andric OS.AddComment("Frontend version"); 700d88c1a5aSDimitry Andric for (int N = 0; N < 4; ++N) 701d88c1a5aSDimitry Andric OS.EmitIntValue(FrontVer.Part[N], 2); 702d88c1a5aSDimitry Andric 703d88c1a5aSDimitry Andric // Some Microsoft tools, like Binscope, expect a backend version number of at 704d88c1a5aSDimitry Andric // least 8.something, so we'll coerce the LLVM version into a form that 705d88c1a5aSDimitry Andric // guarantees it'll be big enough without really lying about the version. 706d88c1a5aSDimitry Andric int Major = 1000 * LLVM_VERSION_MAJOR + 707d88c1a5aSDimitry Andric 10 * LLVM_VERSION_MINOR + 708d88c1a5aSDimitry Andric LLVM_VERSION_PATCH; 709d88c1a5aSDimitry Andric // Clamp it for builds that use unusually large version numbers. 710d88c1a5aSDimitry Andric Major = std::min<int>(Major, std::numeric_limits<uint16_t>::max()); 711d88c1a5aSDimitry Andric Version BackVer = {{ Major, 0, 0, 0 }}; 712d88c1a5aSDimitry Andric OS.AddComment("Backend version"); 713d88c1a5aSDimitry Andric for (int N = 0; N < 4; ++N) 714d88c1a5aSDimitry Andric OS.EmitIntValue(BackVer.Part[N], 2); 715d88c1a5aSDimitry Andric 716d88c1a5aSDimitry Andric OS.AddComment("Null-terminated compiler version string"); 717d88c1a5aSDimitry Andric emitNullTerminatedSymbolName(OS, CompilerVersion); 718d88c1a5aSDimitry Andric 719d88c1a5aSDimitry Andric OS.EmitLabel(CompilerEnd); 720d88c1a5aSDimitry Andric } 721d88c1a5aSDimitry Andric 7223ca95b02SDimitry Andric void CodeViewDebug::emitInlineeLinesSubsection() { 7233ca95b02SDimitry Andric if (InlinedSubprograms.empty()) 7243ca95b02SDimitry Andric return; 7253ca95b02SDimitry Andric 7263ca95b02SDimitry Andric OS.AddComment("Inlinee lines subsection"); 72789cb50c9SDimitry Andric MCSymbol *InlineEnd = beginCVSubsection(DebugSubsectionKind::InlineeLines); 7283ca95b02SDimitry Andric 7292cab237bSDimitry Andric // We emit the checksum info for files. This is used by debuggers to 7302cab237bSDimitry Andric // determine if a pdb matches the source before loading it. Visual Studio, 7312cab237bSDimitry Andric // for instance, will display a warning that the breakpoints are not valid if 7322cab237bSDimitry Andric // the pdb does not match the source. 7333ca95b02SDimitry Andric OS.AddComment("Inlinee lines signature"); 7343ca95b02SDimitry Andric OS.EmitIntValue(unsigned(InlineeLinesSignature::Normal), 4); 7353ca95b02SDimitry Andric 7363ca95b02SDimitry Andric for (const DISubprogram *SP : InlinedSubprograms) { 7373ca95b02SDimitry Andric assert(TypeIndices.count({SP, nullptr})); 7383ca95b02SDimitry Andric TypeIndex InlineeIdx = TypeIndices[{SP, nullptr}]; 7393ca95b02SDimitry Andric 7403ca95b02SDimitry Andric OS.AddBlankLine(); 7413ca95b02SDimitry Andric unsigned FileId = maybeRecordFile(SP->getFile()); 742f37b6182SDimitry Andric OS.AddComment("Inlined function " + SP->getName() + " starts at " + 7433ca95b02SDimitry Andric SP->getFilename() + Twine(':') + Twine(SP->getLine())); 7443ca95b02SDimitry Andric OS.AddBlankLine(); 7453ca95b02SDimitry Andric OS.AddComment("Type index of inlined function"); 7463ca95b02SDimitry Andric OS.EmitIntValue(InlineeIdx.getIndex(), 4); 7473ca95b02SDimitry Andric OS.AddComment("Offset into filechecksum table"); 7482cab237bSDimitry Andric OS.EmitCVFileChecksumOffsetDirective(FileId); 7493ca95b02SDimitry Andric OS.AddComment("Starting line number"); 7503ca95b02SDimitry Andric OS.EmitIntValue(SP->getLine(), 4); 7513ca95b02SDimitry Andric } 7523ca95b02SDimitry Andric 7533ca95b02SDimitry Andric endCVSubsection(InlineEnd); 7543ca95b02SDimitry Andric } 7553ca95b02SDimitry Andric 7563ca95b02SDimitry Andric void CodeViewDebug::emitInlinedCallSite(const FunctionInfo &FI, 7573ca95b02SDimitry Andric const DILocation *InlinedAt, 7583ca95b02SDimitry Andric const InlineSite &Site) { 7593ca95b02SDimitry Andric MCSymbol *InlineBegin = MMI->getContext().createTempSymbol(), 7603ca95b02SDimitry Andric *InlineEnd = MMI->getContext().createTempSymbol(); 7613ca95b02SDimitry Andric 7623ca95b02SDimitry Andric assert(TypeIndices.count({Site.Inlinee, nullptr})); 7633ca95b02SDimitry Andric TypeIndex InlineeIdx = TypeIndices[{Site.Inlinee, nullptr}]; 7643ca95b02SDimitry Andric 7653ca95b02SDimitry Andric // SymbolRecord 7663ca95b02SDimitry Andric OS.AddComment("Record length"); 7673ca95b02SDimitry Andric OS.emitAbsoluteSymbolDiff(InlineEnd, InlineBegin, 2); // RecordLength 7683ca95b02SDimitry Andric OS.EmitLabel(InlineBegin); 7693ca95b02SDimitry Andric OS.AddComment("Record kind: S_INLINESITE"); 7703ca95b02SDimitry Andric OS.EmitIntValue(SymbolKind::S_INLINESITE, 2); // RecordKind 7713ca95b02SDimitry Andric 7723ca95b02SDimitry Andric OS.AddComment("PtrParent"); 7733ca95b02SDimitry Andric OS.EmitIntValue(0, 4); 7743ca95b02SDimitry Andric OS.AddComment("PtrEnd"); 7753ca95b02SDimitry Andric OS.EmitIntValue(0, 4); 7763ca95b02SDimitry Andric OS.AddComment("Inlinee type index"); 7773ca95b02SDimitry Andric OS.EmitIntValue(InlineeIdx.getIndex(), 4); 7783ca95b02SDimitry Andric 7793ca95b02SDimitry Andric unsigned FileId = maybeRecordFile(Site.Inlinee->getFile()); 7803ca95b02SDimitry Andric unsigned StartLineNum = Site.Inlinee->getLine(); 7813ca95b02SDimitry Andric 7823ca95b02SDimitry Andric OS.EmitCVInlineLinetableDirective(Site.SiteFuncId, FileId, StartLineNum, 783d88c1a5aSDimitry Andric FI.Begin, FI.End); 7843ca95b02SDimitry Andric 7853ca95b02SDimitry Andric OS.EmitLabel(InlineEnd); 7863ca95b02SDimitry Andric 7873ca95b02SDimitry Andric emitLocalVariableList(Site.InlinedLocals); 7883ca95b02SDimitry Andric 7893ca95b02SDimitry Andric // Recurse on child inlined call sites before closing the scope. 7903ca95b02SDimitry Andric for (const DILocation *ChildSite : Site.ChildSites) { 7913ca95b02SDimitry Andric auto I = FI.InlineSites.find(ChildSite); 7923ca95b02SDimitry Andric assert(I != FI.InlineSites.end() && 7933ca95b02SDimitry Andric "child site not in function inline site map"); 7943ca95b02SDimitry Andric emitInlinedCallSite(FI, ChildSite, I->second); 7953ca95b02SDimitry Andric } 7963ca95b02SDimitry Andric 7973ca95b02SDimitry Andric // Close the scope. 7983ca95b02SDimitry Andric OS.AddComment("Record length"); 7993ca95b02SDimitry Andric OS.EmitIntValue(2, 2); // RecordLength 8003ca95b02SDimitry Andric OS.AddComment("Record kind: S_INLINESITE_END"); 8013ca95b02SDimitry Andric OS.EmitIntValue(SymbolKind::S_INLINESITE_END, 2); // RecordKind 8023ca95b02SDimitry Andric } 8033ca95b02SDimitry Andric 8043ca95b02SDimitry Andric void CodeViewDebug::switchToDebugSectionForSymbol(const MCSymbol *GVSym) { 8053ca95b02SDimitry Andric // If we have a symbol, it may be in a section that is COMDAT. If so, find the 8063ca95b02SDimitry Andric // comdat key. A section may be comdat because of -ffunction-sections or 8073ca95b02SDimitry Andric // because it is comdat in the IR. 8083ca95b02SDimitry Andric MCSectionCOFF *GVSec = 8093ca95b02SDimitry Andric GVSym ? dyn_cast<MCSectionCOFF>(&GVSym->getSection()) : nullptr; 8103ca95b02SDimitry Andric const MCSymbol *KeySym = GVSec ? GVSec->getCOMDATSymbol() : nullptr; 8113ca95b02SDimitry Andric 8123ca95b02SDimitry Andric MCSectionCOFF *DebugSec = cast<MCSectionCOFF>( 8133ca95b02SDimitry Andric Asm->getObjFileLowering().getCOFFDebugSymbolsSection()); 8143ca95b02SDimitry Andric DebugSec = OS.getContext().getAssociativeCOFFSection(DebugSec, KeySym); 8153ca95b02SDimitry Andric 8163ca95b02SDimitry Andric OS.SwitchSection(DebugSec); 8173ca95b02SDimitry Andric 8183ca95b02SDimitry Andric // Emit the magic version number if this is the first time we've switched to 8193ca95b02SDimitry Andric // this section. 8203ca95b02SDimitry Andric if (ComdatDebugSections.insert(DebugSec).second) 8213ca95b02SDimitry Andric emitCodeViewMagicVersion(); 8223ca95b02SDimitry Andric } 8233ca95b02SDimitry Andric 8243ca95b02SDimitry Andric void CodeViewDebug::emitDebugInfoForFunction(const Function *GV, 8253ca95b02SDimitry Andric FunctionInfo &FI) { 8263ca95b02SDimitry Andric // For each function there is a separate subsection 8273ca95b02SDimitry Andric // which holds the PC to file:line table. 8283ca95b02SDimitry Andric const MCSymbol *Fn = Asm->getSymbol(GV); 8293ca95b02SDimitry Andric assert(Fn); 8303ca95b02SDimitry Andric 8313ca95b02SDimitry Andric // Switch to the to a comdat section, if appropriate. 8323ca95b02SDimitry Andric switchToDebugSectionForSymbol(Fn); 8333ca95b02SDimitry Andric 8343ca95b02SDimitry Andric std::string FuncName; 8353ca95b02SDimitry Andric auto *SP = GV->getSubprogram(); 8366c4bc1bdSDimitry Andric assert(SP); 8373ca95b02SDimitry Andric setCurrentSubprogram(SP); 8383ca95b02SDimitry Andric 8393ca95b02SDimitry Andric // If we have a display name, build the fully qualified name by walking the 8403ca95b02SDimitry Andric // chain of scopes. 841f37b6182SDimitry Andric if (!SP->getName().empty()) 8423ca95b02SDimitry Andric FuncName = 843f37b6182SDimitry Andric getFullyQualifiedName(SP->getScope().resolve(), SP->getName()); 8443ca95b02SDimitry Andric 8453ca95b02SDimitry Andric // If our DISubprogram name is empty, use the mangled name. 8463ca95b02SDimitry Andric if (FuncName.empty()) 8475517e702SDimitry Andric FuncName = GlobalValue::dropLLVMManglingEscape(GV->getName()); 8483ca95b02SDimitry Andric 8492cab237bSDimitry Andric // Emit FPO data, but only on 32-bit x86. No other platforms use it. 8502cab237bSDimitry Andric if (Triple(MMI->getModule()->getTargetTriple()).getArch() == Triple::x86) 8512cab237bSDimitry Andric OS.EmitCVFPOData(Fn); 8522cab237bSDimitry Andric 8533ca95b02SDimitry Andric // Emit a symbol subsection, required by VS2012+ to find function boundaries. 8543ca95b02SDimitry Andric OS.AddComment("Symbol subsection for " + Twine(FuncName)); 85589cb50c9SDimitry Andric MCSymbol *SymbolsEnd = beginCVSubsection(DebugSubsectionKind::Symbols); 8563ca95b02SDimitry Andric { 8573ca95b02SDimitry Andric MCSymbol *ProcRecordBegin = MMI->getContext().createTempSymbol(), 8583ca95b02SDimitry Andric *ProcRecordEnd = MMI->getContext().createTempSymbol(); 8593ca95b02SDimitry Andric OS.AddComment("Record length"); 8603ca95b02SDimitry Andric OS.emitAbsoluteSymbolDiff(ProcRecordEnd, ProcRecordBegin, 2); 8613ca95b02SDimitry Andric OS.EmitLabel(ProcRecordBegin); 8623ca95b02SDimitry Andric 8633ca95b02SDimitry Andric if (GV->hasLocalLinkage()) { 8643ca95b02SDimitry Andric OS.AddComment("Record kind: S_LPROC32_ID"); 8653ca95b02SDimitry Andric OS.EmitIntValue(unsigned(SymbolKind::S_LPROC32_ID), 2); 8663ca95b02SDimitry Andric } else { 8673ca95b02SDimitry Andric OS.AddComment("Record kind: S_GPROC32_ID"); 8683ca95b02SDimitry Andric OS.EmitIntValue(unsigned(SymbolKind::S_GPROC32_ID), 2); 8693ca95b02SDimitry Andric } 8703ca95b02SDimitry Andric 8713ca95b02SDimitry Andric // These fields are filled in by tools like CVPACK which run after the fact. 8723ca95b02SDimitry Andric OS.AddComment("PtrParent"); 8733ca95b02SDimitry Andric OS.EmitIntValue(0, 4); 8743ca95b02SDimitry Andric OS.AddComment("PtrEnd"); 8753ca95b02SDimitry Andric OS.EmitIntValue(0, 4); 8763ca95b02SDimitry Andric OS.AddComment("PtrNext"); 8773ca95b02SDimitry Andric OS.EmitIntValue(0, 4); 8783ca95b02SDimitry Andric // This is the important bit that tells the debugger where the function 8793ca95b02SDimitry Andric // code is located and what's its size: 8803ca95b02SDimitry Andric OS.AddComment("Code size"); 8813ca95b02SDimitry Andric OS.emitAbsoluteSymbolDiff(FI.End, Fn, 4); 8823ca95b02SDimitry Andric OS.AddComment("Offset after prologue"); 8833ca95b02SDimitry Andric OS.EmitIntValue(0, 4); 8843ca95b02SDimitry Andric OS.AddComment("Offset before epilogue"); 8853ca95b02SDimitry Andric OS.EmitIntValue(0, 4); 8863ca95b02SDimitry Andric OS.AddComment("Function type index"); 8873ca95b02SDimitry Andric OS.EmitIntValue(getFuncIdForSubprogram(GV->getSubprogram()).getIndex(), 4); 8883ca95b02SDimitry Andric OS.AddComment("Function section relative address"); 889d88c1a5aSDimitry Andric OS.EmitCOFFSecRel32(Fn, /*Offset=*/0); 8903ca95b02SDimitry Andric OS.AddComment("Function section index"); 8913ca95b02SDimitry Andric OS.EmitCOFFSectionIndex(Fn); 8923ca95b02SDimitry Andric OS.AddComment("Flags"); 8933ca95b02SDimitry Andric OS.EmitIntValue(0, 1); 8943ca95b02SDimitry Andric // Emit the function display name as a null-terminated string. 8953ca95b02SDimitry Andric OS.AddComment("Function name"); 8963ca95b02SDimitry Andric // Truncate the name so we won't overflow the record length field. 8973ca95b02SDimitry Andric emitNullTerminatedSymbolName(OS, FuncName); 8983ca95b02SDimitry Andric OS.EmitLabel(ProcRecordEnd); 8993ca95b02SDimitry Andric 9003ca95b02SDimitry Andric emitLocalVariableList(FI.Locals); 9013ca95b02SDimitry Andric 9023ca95b02SDimitry Andric // Emit inlined call site information. Only emit functions inlined directly 9033ca95b02SDimitry Andric // into the parent function. We'll emit the other sites recursively as part 9043ca95b02SDimitry Andric // of their parent inline site. 9053ca95b02SDimitry Andric for (const DILocation *InlinedAt : FI.ChildSites) { 9063ca95b02SDimitry Andric auto I = FI.InlineSites.find(InlinedAt); 9073ca95b02SDimitry Andric assert(I != FI.InlineSites.end() && 9083ca95b02SDimitry Andric "child site not in function inline site map"); 9093ca95b02SDimitry Andric emitInlinedCallSite(FI, InlinedAt, I->second); 9103ca95b02SDimitry Andric } 9113ca95b02SDimitry Andric 9122cab237bSDimitry Andric for (auto Annot : FI.Annotations) { 9132cab237bSDimitry Andric MCSymbol *Label = Annot.first; 9142cab237bSDimitry Andric MDTuple *Strs = cast<MDTuple>(Annot.second); 9152cab237bSDimitry Andric MCSymbol *AnnotBegin = MMI->getContext().createTempSymbol(), 9162cab237bSDimitry Andric *AnnotEnd = MMI->getContext().createTempSymbol(); 9172cab237bSDimitry Andric OS.AddComment("Record length"); 9182cab237bSDimitry Andric OS.emitAbsoluteSymbolDiff(AnnotEnd, AnnotBegin, 2); 9192cab237bSDimitry Andric OS.EmitLabel(AnnotBegin); 9202cab237bSDimitry Andric OS.AddComment("Record kind: S_ANNOTATION"); 9212cab237bSDimitry Andric OS.EmitIntValue(SymbolKind::S_ANNOTATION, 2); 9222cab237bSDimitry Andric OS.EmitCOFFSecRel32(Label, /*Offset=*/0); 9232cab237bSDimitry Andric // FIXME: Make sure we don't overflow the max record size. 9242cab237bSDimitry Andric OS.EmitCOFFSectionIndex(Label); 9252cab237bSDimitry Andric OS.EmitIntValue(Strs->getNumOperands(), 2); 9262cab237bSDimitry Andric for (Metadata *MD : Strs->operands()) { 9272cab237bSDimitry Andric // MDStrings are null terminated, so we can do EmitBytes and get the 9282cab237bSDimitry Andric // nice .asciz directive. 9292cab237bSDimitry Andric StringRef Str = cast<MDString>(MD)->getString(); 9302cab237bSDimitry Andric assert(Str.data()[Str.size()] == '\0' && "non-nullterminated MDString"); 9312cab237bSDimitry Andric OS.EmitBytes(StringRef(Str.data(), Str.size() + 1)); 9322cab237bSDimitry Andric } 9332cab237bSDimitry Andric OS.EmitLabel(AnnotEnd); 9342cab237bSDimitry Andric } 9352cab237bSDimitry Andric 9363ca95b02SDimitry Andric if (SP != nullptr) 9373ca95b02SDimitry Andric emitDebugInfoForUDTs(LocalUDTs); 9383ca95b02SDimitry Andric 9393ca95b02SDimitry Andric // We're done with this function. 9403ca95b02SDimitry Andric OS.AddComment("Record length"); 9413ca95b02SDimitry Andric OS.EmitIntValue(0x0002, 2); 9423ca95b02SDimitry Andric OS.AddComment("Record kind: S_PROC_ID_END"); 9433ca95b02SDimitry Andric OS.EmitIntValue(unsigned(SymbolKind::S_PROC_ID_END), 2); 9443ca95b02SDimitry Andric } 9453ca95b02SDimitry Andric endCVSubsection(SymbolsEnd); 9463ca95b02SDimitry Andric 9473ca95b02SDimitry Andric // We have an assembler directive that takes care of the whole line table. 9483ca95b02SDimitry Andric OS.EmitCVLinetableDirective(FI.FuncId, Fn, FI.End); 9493ca95b02SDimitry Andric } 9503ca95b02SDimitry Andric 9513ca95b02SDimitry Andric CodeViewDebug::LocalVarDefRange 9523ca95b02SDimitry Andric CodeViewDebug::createDefRangeMem(uint16_t CVRegister, int Offset) { 9533ca95b02SDimitry Andric LocalVarDefRange DR; 9543ca95b02SDimitry Andric DR.InMemory = -1; 9553ca95b02SDimitry Andric DR.DataOffset = Offset; 9563ca95b02SDimitry Andric assert(DR.DataOffset == Offset && "truncation"); 957d88c1a5aSDimitry Andric DR.IsSubfield = 0; 9583ca95b02SDimitry Andric DR.StructOffset = 0; 9593ca95b02SDimitry Andric DR.CVRegister = CVRegister; 9603ca95b02SDimitry Andric return DR; 9613ca95b02SDimitry Andric } 9623ca95b02SDimitry Andric 9633ca95b02SDimitry Andric CodeViewDebug::LocalVarDefRange 964d88c1a5aSDimitry Andric CodeViewDebug::createDefRangeGeneral(uint16_t CVRegister, bool InMemory, 965d88c1a5aSDimitry Andric int Offset, bool IsSubfield, 966d88c1a5aSDimitry Andric uint16_t StructOffset) { 9673ca95b02SDimitry Andric LocalVarDefRange DR; 968d88c1a5aSDimitry Andric DR.InMemory = InMemory; 969d88c1a5aSDimitry Andric DR.DataOffset = Offset; 970d88c1a5aSDimitry Andric DR.IsSubfield = IsSubfield; 971d88c1a5aSDimitry Andric DR.StructOffset = StructOffset; 9723ca95b02SDimitry Andric DR.CVRegister = CVRegister; 9733ca95b02SDimitry Andric return DR; 9743ca95b02SDimitry Andric } 9753ca95b02SDimitry Andric 976d88c1a5aSDimitry Andric void CodeViewDebug::collectVariableInfoFromMFTable( 9773ca95b02SDimitry Andric DenseSet<InlinedVariable> &Processed) { 978d88c1a5aSDimitry Andric const MachineFunction &MF = *Asm->MF; 979d88c1a5aSDimitry Andric const TargetSubtargetInfo &TSI = MF.getSubtarget(); 9803ca95b02SDimitry Andric const TargetFrameLowering *TFI = TSI.getFrameLowering(); 9813ca95b02SDimitry Andric const TargetRegisterInfo *TRI = TSI.getRegisterInfo(); 9823ca95b02SDimitry Andric 983d88c1a5aSDimitry Andric for (const MachineFunction::VariableDbgInfo &VI : MF.getVariableDbgInfo()) { 9843ca95b02SDimitry Andric if (!VI.Var) 9853ca95b02SDimitry Andric continue; 9863ca95b02SDimitry Andric assert(VI.Var->isValidLocationForIntrinsic(VI.Loc) && 9873ca95b02SDimitry Andric "Expected inlined-at fields to agree"); 9883ca95b02SDimitry Andric 9893ca95b02SDimitry Andric Processed.insert(InlinedVariable(VI.Var, VI.Loc->getInlinedAt())); 9903ca95b02SDimitry Andric LexicalScope *Scope = LScopes.findLexicalScope(VI.Loc); 9913ca95b02SDimitry Andric 9923ca95b02SDimitry Andric // If variable scope is not found then skip this variable. 9933ca95b02SDimitry Andric if (!Scope) 9943ca95b02SDimitry Andric continue; 9953ca95b02SDimitry Andric 9965517e702SDimitry Andric // If the variable has an attached offset expression, extract it. 9975517e702SDimitry Andric // FIXME: Try to handle DW_OP_deref as well. 9985517e702SDimitry Andric int64_t ExprOffset = 0; 9995517e702SDimitry Andric if (VI.Expr) 10005517e702SDimitry Andric if (!VI.Expr->extractIfOffset(ExprOffset)) 10015517e702SDimitry Andric continue; 10025517e702SDimitry Andric 10033ca95b02SDimitry Andric // Get the frame register used and the offset. 10043ca95b02SDimitry Andric unsigned FrameReg = 0; 10053ca95b02SDimitry Andric int FrameOffset = TFI->getFrameIndexReference(*Asm->MF, VI.Slot, FrameReg); 10063ca95b02SDimitry Andric uint16_t CVReg = TRI->getCodeViewRegNum(FrameReg); 10073ca95b02SDimitry Andric 10083ca95b02SDimitry Andric // Calculate the label ranges. 10095517e702SDimitry Andric LocalVarDefRange DefRange = 10105517e702SDimitry Andric createDefRangeMem(CVReg, FrameOffset + ExprOffset); 10113ca95b02SDimitry Andric for (const InsnRange &Range : Scope->getRanges()) { 10123ca95b02SDimitry Andric const MCSymbol *Begin = getLabelBeforeInsn(Range.first); 10133ca95b02SDimitry Andric const MCSymbol *End = getLabelAfterInsn(Range.second); 10143ca95b02SDimitry Andric End = End ? End : Asm->getFunctionEnd(); 10153ca95b02SDimitry Andric DefRange.Ranges.emplace_back(Begin, End); 10163ca95b02SDimitry Andric } 10173ca95b02SDimitry Andric 10183ca95b02SDimitry Andric LocalVariable Var; 10193ca95b02SDimitry Andric Var.DIVar = VI.Var; 10203ca95b02SDimitry Andric Var.DefRanges.emplace_back(std::move(DefRange)); 10213ca95b02SDimitry Andric recordLocalVariable(std::move(Var), VI.Loc->getInlinedAt()); 10223ca95b02SDimitry Andric } 10233ca95b02SDimitry Andric } 10243ca95b02SDimitry Andric 10252cab237bSDimitry Andric static bool canUseReferenceType(const DbgVariableLocation &Loc) { 10262cab237bSDimitry Andric return !Loc.LoadChain.empty() && Loc.LoadChain.back() == 0; 10272cab237bSDimitry Andric } 10282cab237bSDimitry Andric 10292cab237bSDimitry Andric static bool needsReferenceType(const DbgVariableLocation &Loc) { 10302cab237bSDimitry Andric return Loc.LoadChain.size() == 2 && Loc.LoadChain.back() == 0; 10312cab237bSDimitry Andric } 10322cab237bSDimitry Andric 10332cab237bSDimitry Andric void CodeViewDebug::calculateRanges( 10342cab237bSDimitry Andric LocalVariable &Var, const DbgValueHistoryMap::InstrRanges &Ranges) { 10352cab237bSDimitry Andric const TargetRegisterInfo *TRI = Asm->MF->getSubtarget().getRegisterInfo(); 10362cab237bSDimitry Andric 10372cab237bSDimitry Andric // Calculate the definition ranges. 10382cab237bSDimitry Andric for (auto I = Ranges.begin(), E = Ranges.end(); I != E; ++I) { 10392cab237bSDimitry Andric const InsnRange &Range = *I; 10402cab237bSDimitry Andric const MachineInstr *DVInst = Range.first; 10412cab237bSDimitry Andric assert(DVInst->isDebugValue() && "Invalid History entry"); 10422cab237bSDimitry Andric // FIXME: Find a way to represent constant variables, since they are 10432cab237bSDimitry Andric // relatively common. 10442cab237bSDimitry Andric Optional<DbgVariableLocation> Location = 10452cab237bSDimitry Andric DbgVariableLocation::extractFromMachineInstruction(*DVInst); 10462cab237bSDimitry Andric if (!Location) 10472cab237bSDimitry Andric continue; 10482cab237bSDimitry Andric 10492cab237bSDimitry Andric // CodeView can only express variables in register and variables in memory 10502cab237bSDimitry Andric // at a constant offset from a register. However, for variables passed 10512cab237bSDimitry Andric // indirectly by pointer, it is common for that pointer to be spilled to a 10522cab237bSDimitry Andric // stack location. For the special case of one offseted load followed by a 10532cab237bSDimitry Andric // zero offset load (a pointer spilled to the stack), we change the type of 10542cab237bSDimitry Andric // the local variable from a value type to a reference type. This tricks the 10552cab237bSDimitry Andric // debugger into doing the load for us. 10562cab237bSDimitry Andric if (Var.UseReferenceType) { 10572cab237bSDimitry Andric // We're using a reference type. Drop the last zero offset load. 10582cab237bSDimitry Andric if (canUseReferenceType(*Location)) 10592cab237bSDimitry Andric Location->LoadChain.pop_back(); 10602cab237bSDimitry Andric else 10612cab237bSDimitry Andric continue; 10622cab237bSDimitry Andric } else if (needsReferenceType(*Location)) { 10632cab237bSDimitry Andric // This location can't be expressed without switching to a reference type. 10642cab237bSDimitry Andric // Start over using that. 10652cab237bSDimitry Andric Var.UseReferenceType = true; 10662cab237bSDimitry Andric Var.DefRanges.clear(); 10672cab237bSDimitry Andric calculateRanges(Var, Ranges); 10682cab237bSDimitry Andric return; 10692cab237bSDimitry Andric } 10702cab237bSDimitry Andric 10712cab237bSDimitry Andric // We can only handle a register or an offseted load of a register. 10722cab237bSDimitry Andric if (Location->Register == 0 || Location->LoadChain.size() > 1) 10732cab237bSDimitry Andric continue; 10742cab237bSDimitry Andric { 10752cab237bSDimitry Andric LocalVarDefRange DR; 10762cab237bSDimitry Andric DR.CVRegister = TRI->getCodeViewRegNum(Location->Register); 10772cab237bSDimitry Andric DR.InMemory = !Location->LoadChain.empty(); 10782cab237bSDimitry Andric DR.DataOffset = 10792cab237bSDimitry Andric !Location->LoadChain.empty() ? Location->LoadChain.back() : 0; 10802cab237bSDimitry Andric if (Location->FragmentInfo) { 10812cab237bSDimitry Andric DR.IsSubfield = true; 10822cab237bSDimitry Andric DR.StructOffset = Location->FragmentInfo->OffsetInBits / 8; 10832cab237bSDimitry Andric } else { 10842cab237bSDimitry Andric DR.IsSubfield = false; 10852cab237bSDimitry Andric DR.StructOffset = 0; 10862cab237bSDimitry Andric } 10872cab237bSDimitry Andric 10882cab237bSDimitry Andric if (Var.DefRanges.empty() || 10892cab237bSDimitry Andric Var.DefRanges.back().isDifferentLocation(DR)) { 10902cab237bSDimitry Andric Var.DefRanges.emplace_back(std::move(DR)); 10912cab237bSDimitry Andric } 10922cab237bSDimitry Andric } 10932cab237bSDimitry Andric 10942cab237bSDimitry Andric // Compute the label range. 10952cab237bSDimitry Andric const MCSymbol *Begin = getLabelBeforeInsn(Range.first); 10962cab237bSDimitry Andric const MCSymbol *End = getLabelAfterInsn(Range.second); 10972cab237bSDimitry Andric if (!End) { 10982cab237bSDimitry Andric // This range is valid until the next overlapping bitpiece. In the 10992cab237bSDimitry Andric // common case, ranges will not be bitpieces, so they will overlap. 11002cab237bSDimitry Andric auto J = std::next(I); 11012cab237bSDimitry Andric const DIExpression *DIExpr = DVInst->getDebugExpression(); 11022cab237bSDimitry Andric while (J != E && 11032cab237bSDimitry Andric !fragmentsOverlap(DIExpr, J->first->getDebugExpression())) 11042cab237bSDimitry Andric ++J; 11052cab237bSDimitry Andric if (J != E) 11062cab237bSDimitry Andric End = getLabelBeforeInsn(J->first); 11072cab237bSDimitry Andric else 11082cab237bSDimitry Andric End = Asm->getFunctionEnd(); 11092cab237bSDimitry Andric } 11102cab237bSDimitry Andric 11112cab237bSDimitry Andric // If the last range end is our begin, just extend the last range. 11122cab237bSDimitry Andric // Otherwise make a new range. 11132cab237bSDimitry Andric SmallVectorImpl<std::pair<const MCSymbol *, const MCSymbol *>> &R = 11142cab237bSDimitry Andric Var.DefRanges.back().Ranges; 11152cab237bSDimitry Andric if (!R.empty() && R.back().second == Begin) 11162cab237bSDimitry Andric R.back().second = End; 11172cab237bSDimitry Andric else 11182cab237bSDimitry Andric R.emplace_back(Begin, End); 11192cab237bSDimitry Andric 11202cab237bSDimitry Andric // FIXME: Do more range combining. 11212cab237bSDimitry Andric } 11222cab237bSDimitry Andric } 11232cab237bSDimitry Andric 11243ca95b02SDimitry Andric void CodeViewDebug::collectVariableInfo(const DISubprogram *SP) { 11253ca95b02SDimitry Andric DenseSet<InlinedVariable> Processed; 11263ca95b02SDimitry Andric // Grab the variable info that was squirreled away in the MMI side-table. 1127d88c1a5aSDimitry Andric collectVariableInfoFromMFTable(Processed); 11283ca95b02SDimitry Andric 11293ca95b02SDimitry Andric for (const auto &I : DbgValues) { 11303ca95b02SDimitry Andric InlinedVariable IV = I.first; 11313ca95b02SDimitry Andric if (Processed.count(IV)) 11323ca95b02SDimitry Andric continue; 11333ca95b02SDimitry Andric const DILocalVariable *DIVar = IV.first; 11343ca95b02SDimitry Andric const DILocation *InlinedAt = IV.second; 11353ca95b02SDimitry Andric 11363ca95b02SDimitry Andric // Instruction ranges, specifying where IV is accessible. 11373ca95b02SDimitry Andric const auto &Ranges = I.second; 11383ca95b02SDimitry Andric 11393ca95b02SDimitry Andric LexicalScope *Scope = nullptr; 11403ca95b02SDimitry Andric if (InlinedAt) 11413ca95b02SDimitry Andric Scope = LScopes.findInlinedScope(DIVar->getScope(), InlinedAt); 11423ca95b02SDimitry Andric else 11433ca95b02SDimitry Andric Scope = LScopes.findLexicalScope(DIVar->getScope()); 11443ca95b02SDimitry Andric // If variable scope is not found then skip this variable. 11453ca95b02SDimitry Andric if (!Scope) 11463ca95b02SDimitry Andric continue; 11473ca95b02SDimitry Andric 11483ca95b02SDimitry Andric LocalVariable Var; 11493ca95b02SDimitry Andric Var.DIVar = DIVar; 11503ca95b02SDimitry Andric 11512cab237bSDimitry Andric calculateRanges(Var, Ranges); 11523ca95b02SDimitry Andric recordLocalVariable(std::move(Var), InlinedAt); 11533ca95b02SDimitry Andric } 11543ca95b02SDimitry Andric } 11553ca95b02SDimitry Andric 11567a7e6055SDimitry Andric void CodeViewDebug::beginFunctionImpl(const MachineFunction *MF) { 11572cab237bSDimitry Andric const Function &GV = MF->getFunction(); 11582cab237bSDimitry Andric assert(FnDebugInfo.count(&GV) == false); 11592cab237bSDimitry Andric CurFn = &FnDebugInfo[&GV]; 11603ca95b02SDimitry Andric CurFn->FuncId = NextFuncId++; 11613ca95b02SDimitry Andric CurFn->Begin = Asm->getFunctionBegin(); 11623ca95b02SDimitry Andric 1163d88c1a5aSDimitry Andric OS.EmitCVFuncIdDirective(CurFn->FuncId); 1164d88c1a5aSDimitry Andric 11653ca95b02SDimitry Andric // Find the end of the function prolog. First known non-DBG_VALUE and 11663ca95b02SDimitry Andric // non-frame setup location marks the beginning of the function body. 11673ca95b02SDimitry Andric // FIXME: is there a simpler a way to do this? Can we just search 11683ca95b02SDimitry Andric // for the first instruction of the function, not the last of the prolog? 11693ca95b02SDimitry Andric DebugLoc PrologEndLoc; 11703ca95b02SDimitry Andric bool EmptyPrologue = true; 11713ca95b02SDimitry Andric for (const auto &MBB : *MF) { 11723ca95b02SDimitry Andric for (const auto &MI : MBB) { 1173302affcbSDimitry Andric if (!MI.isMetaInstruction() && !MI.getFlag(MachineInstr::FrameSetup) && 11743ca95b02SDimitry Andric MI.getDebugLoc()) { 11753ca95b02SDimitry Andric PrologEndLoc = MI.getDebugLoc(); 11763ca95b02SDimitry Andric break; 1177302affcbSDimitry Andric } else if (!MI.isMetaInstruction()) { 11783ca95b02SDimitry Andric EmptyPrologue = false; 11793ca95b02SDimitry Andric } 11803ca95b02SDimitry Andric } 11813ca95b02SDimitry Andric } 11823ca95b02SDimitry Andric 11833ca95b02SDimitry Andric // Record beginning of function if we have a non-empty prologue. 11843ca95b02SDimitry Andric if (PrologEndLoc && !EmptyPrologue) { 11853ca95b02SDimitry Andric DebugLoc FnStartDL = PrologEndLoc.getFnDebugLoc(); 11863ca95b02SDimitry Andric maybeRecordLocation(FnStartDL, MF); 11873ca95b02SDimitry Andric } 11883ca95b02SDimitry Andric } 11893ca95b02SDimitry Andric 11902cab237bSDimitry Andric static bool shouldEmitUdt(const DIType *T) { 11912cab237bSDimitry Andric if (!T) 11922cab237bSDimitry Andric return false; 11932cab237bSDimitry Andric 11942cab237bSDimitry Andric // MSVC does not emit UDTs for typedefs that are scoped to classes. 11952cab237bSDimitry Andric if (T->getTag() == dwarf::DW_TAG_typedef) { 11962cab237bSDimitry Andric if (DIScope *Scope = T->getScope().resolve()) { 11972cab237bSDimitry Andric switch (Scope->getTag()) { 11982cab237bSDimitry Andric case dwarf::DW_TAG_structure_type: 11992cab237bSDimitry Andric case dwarf::DW_TAG_class_type: 12002cab237bSDimitry Andric case dwarf::DW_TAG_union_type: 12012cab237bSDimitry Andric return false; 12022cab237bSDimitry Andric } 12032cab237bSDimitry Andric } 12042cab237bSDimitry Andric } 12052cab237bSDimitry Andric 12062cab237bSDimitry Andric while (true) { 12072cab237bSDimitry Andric if (!T || T->isForwardDecl()) 12082cab237bSDimitry Andric return false; 12092cab237bSDimitry Andric 12102cab237bSDimitry Andric const DIDerivedType *DT = dyn_cast<DIDerivedType>(T); 12112cab237bSDimitry Andric if (!DT) 12122cab237bSDimitry Andric return true; 12132cab237bSDimitry Andric T = DT->getBaseType().resolve(); 12142cab237bSDimitry Andric } 12152cab237bSDimitry Andric return true; 12162cab237bSDimitry Andric } 12172cab237bSDimitry Andric 12182cab237bSDimitry Andric void CodeViewDebug::addToUDTs(const DIType *Ty) { 12193ca95b02SDimitry Andric // Don't record empty UDTs. 12203ca95b02SDimitry Andric if (Ty->getName().empty()) 12213ca95b02SDimitry Andric return; 12222cab237bSDimitry Andric if (!shouldEmitUdt(Ty)) 12232cab237bSDimitry Andric return; 12243ca95b02SDimitry Andric 12253ca95b02SDimitry Andric SmallVector<StringRef, 5> QualifiedNameComponents; 12263ca95b02SDimitry Andric const DISubprogram *ClosestSubprogram = getQualifiedNameComponents( 12273ca95b02SDimitry Andric Ty->getScope().resolve(), QualifiedNameComponents); 12283ca95b02SDimitry Andric 12293ca95b02SDimitry Andric std::string FullyQualifiedName = 12303ca95b02SDimitry Andric getQualifiedName(QualifiedNameComponents, getPrettyScopeName(Ty)); 12313ca95b02SDimitry Andric 12322cab237bSDimitry Andric if (ClosestSubprogram == nullptr) { 12332cab237bSDimitry Andric GlobalUDTs.emplace_back(std::move(FullyQualifiedName), Ty); 12342cab237bSDimitry Andric } else if (ClosestSubprogram == CurrentSubprogram) { 12352cab237bSDimitry Andric LocalUDTs.emplace_back(std::move(FullyQualifiedName), Ty); 12362cab237bSDimitry Andric } 12373ca95b02SDimitry Andric 12383ca95b02SDimitry Andric // TODO: What if the ClosestSubprogram is neither null or the current 12393ca95b02SDimitry Andric // subprogram? Currently, the UDT just gets dropped on the floor. 12403ca95b02SDimitry Andric // 12413ca95b02SDimitry Andric // The current behavior is not desirable. To get maximal fidelity, we would 12423ca95b02SDimitry Andric // need to perform all type translation before beginning emission of .debug$S 12433ca95b02SDimitry Andric // and then make LocalUDTs a member of FunctionInfo 12443ca95b02SDimitry Andric } 12453ca95b02SDimitry Andric 12463ca95b02SDimitry Andric TypeIndex CodeViewDebug::lowerType(const DIType *Ty, const DIType *ClassTy) { 12473ca95b02SDimitry Andric // Generic dispatch for lowering an unknown type. 12483ca95b02SDimitry Andric switch (Ty->getTag()) { 12493ca95b02SDimitry Andric case dwarf::DW_TAG_array_type: 12503ca95b02SDimitry Andric return lowerTypeArray(cast<DICompositeType>(Ty)); 12513ca95b02SDimitry Andric case dwarf::DW_TAG_typedef: 12523ca95b02SDimitry Andric return lowerTypeAlias(cast<DIDerivedType>(Ty)); 12533ca95b02SDimitry Andric case dwarf::DW_TAG_base_type: 12543ca95b02SDimitry Andric return lowerTypeBasic(cast<DIBasicType>(Ty)); 12553ca95b02SDimitry Andric case dwarf::DW_TAG_pointer_type: 1256d88c1a5aSDimitry Andric if (cast<DIDerivedType>(Ty)->getName() == "__vtbl_ptr_type") 1257d88c1a5aSDimitry Andric return lowerTypeVFTableShape(cast<DIDerivedType>(Ty)); 1258d88c1a5aSDimitry Andric LLVM_FALLTHROUGH; 12593ca95b02SDimitry Andric case dwarf::DW_TAG_reference_type: 12603ca95b02SDimitry Andric case dwarf::DW_TAG_rvalue_reference_type: 12613ca95b02SDimitry Andric return lowerTypePointer(cast<DIDerivedType>(Ty)); 12623ca95b02SDimitry Andric case dwarf::DW_TAG_ptr_to_member_type: 12633ca95b02SDimitry Andric return lowerTypeMemberPointer(cast<DIDerivedType>(Ty)); 12643ca95b02SDimitry Andric case dwarf::DW_TAG_const_type: 12653ca95b02SDimitry Andric case dwarf::DW_TAG_volatile_type: 1266d88c1a5aSDimitry Andric // TODO: add support for DW_TAG_atomic_type here 12673ca95b02SDimitry Andric return lowerTypeModifier(cast<DIDerivedType>(Ty)); 12683ca95b02SDimitry Andric case dwarf::DW_TAG_subroutine_type: 12693ca95b02SDimitry Andric if (ClassTy) { 12703ca95b02SDimitry Andric // The member function type of a member function pointer has no 12713ca95b02SDimitry Andric // ThisAdjustment. 12723ca95b02SDimitry Andric return lowerTypeMemberFunction(cast<DISubroutineType>(Ty), ClassTy, 12732cab237bSDimitry Andric /*ThisAdjustment=*/0, 12742cab237bSDimitry Andric /*IsStaticMethod=*/false); 12753ca95b02SDimitry Andric } 12763ca95b02SDimitry Andric return lowerTypeFunction(cast<DISubroutineType>(Ty)); 12773ca95b02SDimitry Andric case dwarf::DW_TAG_enumeration_type: 12783ca95b02SDimitry Andric return lowerTypeEnum(cast<DICompositeType>(Ty)); 12793ca95b02SDimitry Andric case dwarf::DW_TAG_class_type: 12803ca95b02SDimitry Andric case dwarf::DW_TAG_structure_type: 12813ca95b02SDimitry Andric return lowerTypeClass(cast<DICompositeType>(Ty)); 12823ca95b02SDimitry Andric case dwarf::DW_TAG_union_type: 12833ca95b02SDimitry Andric return lowerTypeUnion(cast<DICompositeType>(Ty)); 12843ca95b02SDimitry Andric default: 12853ca95b02SDimitry Andric // Use the null type index. 12863ca95b02SDimitry Andric return TypeIndex(); 12873ca95b02SDimitry Andric } 12883ca95b02SDimitry Andric } 12893ca95b02SDimitry Andric 12903ca95b02SDimitry Andric TypeIndex CodeViewDebug::lowerTypeAlias(const DIDerivedType *Ty) { 12913ca95b02SDimitry Andric DITypeRef UnderlyingTypeRef = Ty->getBaseType(); 12923ca95b02SDimitry Andric TypeIndex UnderlyingTypeIndex = getTypeIndex(UnderlyingTypeRef); 12933ca95b02SDimitry Andric StringRef TypeName = Ty->getName(); 12943ca95b02SDimitry Andric 12952cab237bSDimitry Andric addToUDTs(Ty); 12963ca95b02SDimitry Andric 12973ca95b02SDimitry Andric if (UnderlyingTypeIndex == TypeIndex(SimpleTypeKind::Int32Long) && 12983ca95b02SDimitry Andric TypeName == "HRESULT") 12993ca95b02SDimitry Andric return TypeIndex(SimpleTypeKind::HResult); 13003ca95b02SDimitry Andric if (UnderlyingTypeIndex == TypeIndex(SimpleTypeKind::UInt16Short) && 13013ca95b02SDimitry Andric TypeName == "wchar_t") 13023ca95b02SDimitry Andric return TypeIndex(SimpleTypeKind::WideCharacter); 13033ca95b02SDimitry Andric 13043ca95b02SDimitry Andric return UnderlyingTypeIndex; 13053ca95b02SDimitry Andric } 13063ca95b02SDimitry Andric 13073ca95b02SDimitry Andric TypeIndex CodeViewDebug::lowerTypeArray(const DICompositeType *Ty) { 13083ca95b02SDimitry Andric DITypeRef ElementTypeRef = Ty->getBaseType(); 13093ca95b02SDimitry Andric TypeIndex ElementTypeIndex = getTypeIndex(ElementTypeRef); 13103ca95b02SDimitry Andric // IndexType is size_t, which depends on the bitness of the target. 13116bc11b14SDimitry Andric TypeIndex IndexType = Asm->TM.getPointerSize() == 8 13123ca95b02SDimitry Andric ? TypeIndex(SimpleTypeKind::UInt64Quad) 13133ca95b02SDimitry Andric : TypeIndex(SimpleTypeKind::UInt32Long); 13143ca95b02SDimitry Andric 13153ca95b02SDimitry Andric uint64_t ElementSize = getBaseTypeSize(ElementTypeRef) / 8; 13163ca95b02SDimitry Andric 13173ca95b02SDimitry Andric // Add subranges to array type. 13183ca95b02SDimitry Andric DINodeArray Elements = Ty->getElements(); 13193ca95b02SDimitry Andric for (int i = Elements.size() - 1; i >= 0; --i) { 13203ca95b02SDimitry Andric const DINode *Element = Elements[i]; 13213ca95b02SDimitry Andric assert(Element->getTag() == dwarf::DW_TAG_subrange_type); 13223ca95b02SDimitry Andric 13233ca95b02SDimitry Andric const DISubrange *Subrange = cast<DISubrange>(Element); 13243ca95b02SDimitry Andric assert(Subrange->getLowerBound() == 0 && 13253ca95b02SDimitry Andric "codeview doesn't support subranges with lower bounds"); 13263ca95b02SDimitry Andric int64_t Count = Subrange->getCount(); 13273ca95b02SDimitry Andric 13282cab237bSDimitry Andric // Forward declarations of arrays without a size and VLAs use a count of -1. 13292cab237bSDimitry Andric // Emit a count of zero in these cases to match what MSVC does for arrays 13302cab237bSDimitry Andric // without a size. MSVC doesn't support VLAs, so it's not clear what we 13312cab237bSDimitry Andric // should do for them even if we could distinguish them. 13327a7e6055SDimitry Andric if (Count == -1) 13332cab237bSDimitry Andric Count = 0; 13343ca95b02SDimitry Andric 13353ca95b02SDimitry Andric // Update the element size and element type index for subsequent subranges. 13363ca95b02SDimitry Andric ElementSize *= Count; 1337d88c1a5aSDimitry Andric 1338d88c1a5aSDimitry Andric // If this is the outermost array, use the size from the array. It will be 13397a7e6055SDimitry Andric // more accurate if we had a VLA or an incomplete element type size. 1340d88c1a5aSDimitry Andric uint64_t ArraySize = 1341d88c1a5aSDimitry Andric (i == 0 && ElementSize == 0) ? Ty->getSizeInBits() / 8 : ElementSize; 1342d88c1a5aSDimitry Andric 1343d88c1a5aSDimitry Andric StringRef Name = (i == 0) ? Ty->getName() : ""; 1344d88c1a5aSDimitry Andric ArrayRecord AR(ElementTypeIndex, IndexType, ArraySize, Name); 13452cab237bSDimitry Andric ElementTypeIndex = TypeTable.writeLeafType(AR); 13463ca95b02SDimitry Andric } 13473ca95b02SDimitry Andric 13483ca95b02SDimitry Andric return ElementTypeIndex; 13493ca95b02SDimitry Andric } 13503ca95b02SDimitry Andric 13513ca95b02SDimitry Andric TypeIndex CodeViewDebug::lowerTypeBasic(const DIBasicType *Ty) { 13523ca95b02SDimitry Andric TypeIndex Index; 13533ca95b02SDimitry Andric dwarf::TypeKind Kind; 13543ca95b02SDimitry Andric uint32_t ByteSize; 13553ca95b02SDimitry Andric 13563ca95b02SDimitry Andric Kind = static_cast<dwarf::TypeKind>(Ty->getEncoding()); 13573ca95b02SDimitry Andric ByteSize = Ty->getSizeInBits() / 8; 13583ca95b02SDimitry Andric 13593ca95b02SDimitry Andric SimpleTypeKind STK = SimpleTypeKind::None; 13603ca95b02SDimitry Andric switch (Kind) { 13613ca95b02SDimitry Andric case dwarf::DW_ATE_address: 13623ca95b02SDimitry Andric // FIXME: Translate 13633ca95b02SDimitry Andric break; 13643ca95b02SDimitry Andric case dwarf::DW_ATE_boolean: 13653ca95b02SDimitry Andric switch (ByteSize) { 13663ca95b02SDimitry Andric case 1: STK = SimpleTypeKind::Boolean8; break; 13673ca95b02SDimitry Andric case 2: STK = SimpleTypeKind::Boolean16; break; 13683ca95b02SDimitry Andric case 4: STK = SimpleTypeKind::Boolean32; break; 13693ca95b02SDimitry Andric case 8: STK = SimpleTypeKind::Boolean64; break; 13703ca95b02SDimitry Andric case 16: STK = SimpleTypeKind::Boolean128; break; 13713ca95b02SDimitry Andric } 13723ca95b02SDimitry Andric break; 13733ca95b02SDimitry Andric case dwarf::DW_ATE_complex_float: 13743ca95b02SDimitry Andric switch (ByteSize) { 13753ca95b02SDimitry Andric case 2: STK = SimpleTypeKind::Complex16; break; 13763ca95b02SDimitry Andric case 4: STK = SimpleTypeKind::Complex32; break; 13773ca95b02SDimitry Andric case 8: STK = SimpleTypeKind::Complex64; break; 13783ca95b02SDimitry Andric case 10: STK = SimpleTypeKind::Complex80; break; 13793ca95b02SDimitry Andric case 16: STK = SimpleTypeKind::Complex128; break; 13803ca95b02SDimitry Andric } 13813ca95b02SDimitry Andric break; 13823ca95b02SDimitry Andric case dwarf::DW_ATE_float: 13833ca95b02SDimitry Andric switch (ByteSize) { 13843ca95b02SDimitry Andric case 2: STK = SimpleTypeKind::Float16; break; 13853ca95b02SDimitry Andric case 4: STK = SimpleTypeKind::Float32; break; 13863ca95b02SDimitry Andric case 6: STK = SimpleTypeKind::Float48; break; 13873ca95b02SDimitry Andric case 8: STK = SimpleTypeKind::Float64; break; 13883ca95b02SDimitry Andric case 10: STK = SimpleTypeKind::Float80; break; 13893ca95b02SDimitry Andric case 16: STK = SimpleTypeKind::Float128; break; 13903ca95b02SDimitry Andric } 13913ca95b02SDimitry Andric break; 13923ca95b02SDimitry Andric case dwarf::DW_ATE_signed: 13933ca95b02SDimitry Andric switch (ByteSize) { 1394d88c1a5aSDimitry Andric case 1: STK = SimpleTypeKind::SignedCharacter; break; 13953ca95b02SDimitry Andric case 2: STK = SimpleTypeKind::Int16Short; break; 13963ca95b02SDimitry Andric case 4: STK = SimpleTypeKind::Int32; break; 13973ca95b02SDimitry Andric case 8: STK = SimpleTypeKind::Int64Quad; break; 13983ca95b02SDimitry Andric case 16: STK = SimpleTypeKind::Int128Oct; break; 13993ca95b02SDimitry Andric } 14003ca95b02SDimitry Andric break; 14013ca95b02SDimitry Andric case dwarf::DW_ATE_unsigned: 14023ca95b02SDimitry Andric switch (ByteSize) { 1403d88c1a5aSDimitry Andric case 1: STK = SimpleTypeKind::UnsignedCharacter; break; 14043ca95b02SDimitry Andric case 2: STK = SimpleTypeKind::UInt16Short; break; 14053ca95b02SDimitry Andric case 4: STK = SimpleTypeKind::UInt32; break; 14063ca95b02SDimitry Andric case 8: STK = SimpleTypeKind::UInt64Quad; break; 14073ca95b02SDimitry Andric case 16: STK = SimpleTypeKind::UInt128Oct; break; 14083ca95b02SDimitry Andric } 14093ca95b02SDimitry Andric break; 14103ca95b02SDimitry Andric case dwarf::DW_ATE_UTF: 14113ca95b02SDimitry Andric switch (ByteSize) { 14123ca95b02SDimitry Andric case 2: STK = SimpleTypeKind::Character16; break; 14133ca95b02SDimitry Andric case 4: STK = SimpleTypeKind::Character32; break; 14143ca95b02SDimitry Andric } 14153ca95b02SDimitry Andric break; 14163ca95b02SDimitry Andric case dwarf::DW_ATE_signed_char: 14173ca95b02SDimitry Andric if (ByteSize == 1) 14183ca95b02SDimitry Andric STK = SimpleTypeKind::SignedCharacter; 14193ca95b02SDimitry Andric break; 14203ca95b02SDimitry Andric case dwarf::DW_ATE_unsigned_char: 14213ca95b02SDimitry Andric if (ByteSize == 1) 14223ca95b02SDimitry Andric STK = SimpleTypeKind::UnsignedCharacter; 14233ca95b02SDimitry Andric break; 14243ca95b02SDimitry Andric default: 14253ca95b02SDimitry Andric break; 14263ca95b02SDimitry Andric } 14273ca95b02SDimitry Andric 14283ca95b02SDimitry Andric // Apply some fixups based on the source-level type name. 14293ca95b02SDimitry Andric if (STK == SimpleTypeKind::Int32 && Ty->getName() == "long int") 14303ca95b02SDimitry Andric STK = SimpleTypeKind::Int32Long; 14313ca95b02SDimitry Andric if (STK == SimpleTypeKind::UInt32 && Ty->getName() == "long unsigned int") 14323ca95b02SDimitry Andric STK = SimpleTypeKind::UInt32Long; 14333ca95b02SDimitry Andric if (STK == SimpleTypeKind::UInt16Short && 14343ca95b02SDimitry Andric (Ty->getName() == "wchar_t" || Ty->getName() == "__wchar_t")) 14353ca95b02SDimitry Andric STK = SimpleTypeKind::WideCharacter; 14363ca95b02SDimitry Andric if ((STK == SimpleTypeKind::SignedCharacter || 14373ca95b02SDimitry Andric STK == SimpleTypeKind::UnsignedCharacter) && 14383ca95b02SDimitry Andric Ty->getName() == "char") 14393ca95b02SDimitry Andric STK = SimpleTypeKind::NarrowCharacter; 14403ca95b02SDimitry Andric 14413ca95b02SDimitry Andric return TypeIndex(STK); 14423ca95b02SDimitry Andric } 14433ca95b02SDimitry Andric 14443ca95b02SDimitry Andric TypeIndex CodeViewDebug::lowerTypePointer(const DIDerivedType *Ty) { 14453ca95b02SDimitry Andric TypeIndex PointeeTI = getTypeIndex(Ty->getBaseType()); 14463ca95b02SDimitry Andric 14473ca95b02SDimitry Andric // Pointers to simple types can use SimpleTypeMode, rather than having a 14483ca95b02SDimitry Andric // dedicated pointer type record. 14493ca95b02SDimitry Andric if (PointeeTI.isSimple() && 14503ca95b02SDimitry Andric PointeeTI.getSimpleMode() == SimpleTypeMode::Direct && 14513ca95b02SDimitry Andric Ty->getTag() == dwarf::DW_TAG_pointer_type) { 14523ca95b02SDimitry Andric SimpleTypeMode Mode = Ty->getSizeInBits() == 64 14533ca95b02SDimitry Andric ? SimpleTypeMode::NearPointer64 14543ca95b02SDimitry Andric : SimpleTypeMode::NearPointer32; 14553ca95b02SDimitry Andric return TypeIndex(PointeeTI.getSimpleKind(), Mode); 14563ca95b02SDimitry Andric } 14573ca95b02SDimitry Andric 14583ca95b02SDimitry Andric PointerKind PK = 14593ca95b02SDimitry Andric Ty->getSizeInBits() == 64 ? PointerKind::Near64 : PointerKind::Near32; 14603ca95b02SDimitry Andric PointerMode PM = PointerMode::Pointer; 14613ca95b02SDimitry Andric switch (Ty->getTag()) { 14623ca95b02SDimitry Andric default: llvm_unreachable("not a pointer tag type"); 14633ca95b02SDimitry Andric case dwarf::DW_TAG_pointer_type: 14643ca95b02SDimitry Andric PM = PointerMode::Pointer; 14653ca95b02SDimitry Andric break; 14663ca95b02SDimitry Andric case dwarf::DW_TAG_reference_type: 14673ca95b02SDimitry Andric PM = PointerMode::LValueReference; 14683ca95b02SDimitry Andric break; 14693ca95b02SDimitry Andric case dwarf::DW_TAG_rvalue_reference_type: 14703ca95b02SDimitry Andric PM = PointerMode::RValueReference; 14713ca95b02SDimitry Andric break; 14723ca95b02SDimitry Andric } 14733ca95b02SDimitry Andric // FIXME: MSVC folds qualifiers into PointerOptions in the context of a method 14743ca95b02SDimitry Andric // 'this' pointer, but not normal contexts. Figure out what we're supposed to 14753ca95b02SDimitry Andric // do. 14763ca95b02SDimitry Andric PointerOptions PO = PointerOptions::None; 14773ca95b02SDimitry Andric PointerRecord PR(PointeeTI, PK, PM, PO, Ty->getSizeInBits() / 8); 14782cab237bSDimitry Andric return TypeTable.writeLeafType(PR); 14793ca95b02SDimitry Andric } 14803ca95b02SDimitry Andric 14813ca95b02SDimitry Andric static PointerToMemberRepresentation 14823ca95b02SDimitry Andric translatePtrToMemberRep(unsigned SizeInBytes, bool IsPMF, unsigned Flags) { 14833ca95b02SDimitry Andric // SizeInBytes being zero generally implies that the member pointer type was 14843ca95b02SDimitry Andric // incomplete, which can happen if it is part of a function prototype. In this 14853ca95b02SDimitry Andric // case, use the unknown model instead of the general model. 14863ca95b02SDimitry Andric if (IsPMF) { 14873ca95b02SDimitry Andric switch (Flags & DINode::FlagPtrToMemberRep) { 14883ca95b02SDimitry Andric case 0: 14893ca95b02SDimitry Andric return SizeInBytes == 0 ? PointerToMemberRepresentation::Unknown 14903ca95b02SDimitry Andric : PointerToMemberRepresentation::GeneralFunction; 14913ca95b02SDimitry Andric case DINode::FlagSingleInheritance: 14923ca95b02SDimitry Andric return PointerToMemberRepresentation::SingleInheritanceFunction; 14933ca95b02SDimitry Andric case DINode::FlagMultipleInheritance: 14943ca95b02SDimitry Andric return PointerToMemberRepresentation::MultipleInheritanceFunction; 14953ca95b02SDimitry Andric case DINode::FlagVirtualInheritance: 14963ca95b02SDimitry Andric return PointerToMemberRepresentation::VirtualInheritanceFunction; 14973ca95b02SDimitry Andric } 14983ca95b02SDimitry Andric } else { 14993ca95b02SDimitry Andric switch (Flags & DINode::FlagPtrToMemberRep) { 15003ca95b02SDimitry Andric case 0: 15013ca95b02SDimitry Andric return SizeInBytes == 0 ? PointerToMemberRepresentation::Unknown 15023ca95b02SDimitry Andric : PointerToMemberRepresentation::GeneralData; 15033ca95b02SDimitry Andric case DINode::FlagSingleInheritance: 15043ca95b02SDimitry Andric return PointerToMemberRepresentation::SingleInheritanceData; 15053ca95b02SDimitry Andric case DINode::FlagMultipleInheritance: 15063ca95b02SDimitry Andric return PointerToMemberRepresentation::MultipleInheritanceData; 15073ca95b02SDimitry Andric case DINode::FlagVirtualInheritance: 15083ca95b02SDimitry Andric return PointerToMemberRepresentation::VirtualInheritanceData; 15093ca95b02SDimitry Andric } 15103ca95b02SDimitry Andric } 15113ca95b02SDimitry Andric llvm_unreachable("invalid ptr to member representation"); 15123ca95b02SDimitry Andric } 15133ca95b02SDimitry Andric 15143ca95b02SDimitry Andric TypeIndex CodeViewDebug::lowerTypeMemberPointer(const DIDerivedType *Ty) { 15153ca95b02SDimitry Andric assert(Ty->getTag() == dwarf::DW_TAG_ptr_to_member_type); 15163ca95b02SDimitry Andric TypeIndex ClassTI = getTypeIndex(Ty->getClassType()); 15173ca95b02SDimitry Andric TypeIndex PointeeTI = getTypeIndex(Ty->getBaseType(), Ty->getClassType()); 15186bc11b14SDimitry Andric PointerKind PK = Asm->TM.getPointerSize() == 8 ? PointerKind::Near64 15193ca95b02SDimitry Andric : PointerKind::Near32; 15203ca95b02SDimitry Andric bool IsPMF = isa<DISubroutineType>(Ty->getBaseType()); 15213ca95b02SDimitry Andric PointerMode PM = IsPMF ? PointerMode::PointerToMemberFunction 15223ca95b02SDimitry Andric : PointerMode::PointerToDataMember; 15233ca95b02SDimitry Andric PointerOptions PO = PointerOptions::None; // FIXME 15243ca95b02SDimitry Andric assert(Ty->getSizeInBits() / 8 <= 0xff && "pointer size too big"); 15253ca95b02SDimitry Andric uint8_t SizeInBytes = Ty->getSizeInBits() / 8; 15263ca95b02SDimitry Andric MemberPointerInfo MPI( 15273ca95b02SDimitry Andric ClassTI, translatePtrToMemberRep(SizeInBytes, IsPMF, Ty->getFlags())); 15283ca95b02SDimitry Andric PointerRecord PR(PointeeTI, PK, PM, PO, SizeInBytes, MPI); 15292cab237bSDimitry Andric return TypeTable.writeLeafType(PR); 15303ca95b02SDimitry Andric } 15313ca95b02SDimitry Andric 15323ca95b02SDimitry Andric /// Given a DWARF calling convention, get the CodeView equivalent. If we don't 15333ca95b02SDimitry Andric /// have a translation, use the NearC convention. 15343ca95b02SDimitry Andric static CallingConvention dwarfCCToCodeView(unsigned DwarfCC) { 15353ca95b02SDimitry Andric switch (DwarfCC) { 15363ca95b02SDimitry Andric case dwarf::DW_CC_normal: return CallingConvention::NearC; 15373ca95b02SDimitry Andric case dwarf::DW_CC_BORLAND_msfastcall: return CallingConvention::NearFast; 15383ca95b02SDimitry Andric case dwarf::DW_CC_BORLAND_thiscall: return CallingConvention::ThisCall; 15393ca95b02SDimitry Andric case dwarf::DW_CC_BORLAND_stdcall: return CallingConvention::NearStdCall; 15403ca95b02SDimitry Andric case dwarf::DW_CC_BORLAND_pascal: return CallingConvention::NearPascal; 15413ca95b02SDimitry Andric case dwarf::DW_CC_LLVM_vectorcall: return CallingConvention::NearVector; 15423ca95b02SDimitry Andric } 15433ca95b02SDimitry Andric return CallingConvention::NearC; 15443ca95b02SDimitry Andric } 15453ca95b02SDimitry Andric 15463ca95b02SDimitry Andric TypeIndex CodeViewDebug::lowerTypeModifier(const DIDerivedType *Ty) { 15473ca95b02SDimitry Andric ModifierOptions Mods = ModifierOptions::None; 15483ca95b02SDimitry Andric bool IsModifier = true; 15493ca95b02SDimitry Andric const DIType *BaseTy = Ty; 15503ca95b02SDimitry Andric while (IsModifier && BaseTy) { 1551d88c1a5aSDimitry Andric // FIXME: Need to add DWARF tags for __unaligned and _Atomic 15523ca95b02SDimitry Andric switch (BaseTy->getTag()) { 15533ca95b02SDimitry Andric case dwarf::DW_TAG_const_type: 15543ca95b02SDimitry Andric Mods |= ModifierOptions::Const; 15553ca95b02SDimitry Andric break; 15563ca95b02SDimitry Andric case dwarf::DW_TAG_volatile_type: 15573ca95b02SDimitry Andric Mods |= ModifierOptions::Volatile; 15583ca95b02SDimitry Andric break; 15593ca95b02SDimitry Andric default: 15603ca95b02SDimitry Andric IsModifier = false; 15613ca95b02SDimitry Andric break; 15623ca95b02SDimitry Andric } 15633ca95b02SDimitry Andric if (IsModifier) 15643ca95b02SDimitry Andric BaseTy = cast<DIDerivedType>(BaseTy)->getBaseType().resolve(); 15653ca95b02SDimitry Andric } 15663ca95b02SDimitry Andric TypeIndex ModifiedTI = getTypeIndex(BaseTy); 15673ca95b02SDimitry Andric ModifierRecord MR(ModifiedTI, Mods); 15682cab237bSDimitry Andric return TypeTable.writeLeafType(MR); 15693ca95b02SDimitry Andric } 15703ca95b02SDimitry Andric 15713ca95b02SDimitry Andric TypeIndex CodeViewDebug::lowerTypeFunction(const DISubroutineType *Ty) { 15723ca95b02SDimitry Andric SmallVector<TypeIndex, 8> ReturnAndArgTypeIndices; 15733ca95b02SDimitry Andric for (DITypeRef ArgTypeRef : Ty->getTypeArray()) 15743ca95b02SDimitry Andric ReturnAndArgTypeIndices.push_back(getTypeIndex(ArgTypeRef)); 15753ca95b02SDimitry Andric 15763ca95b02SDimitry Andric TypeIndex ReturnTypeIndex = TypeIndex::Void(); 15773ca95b02SDimitry Andric ArrayRef<TypeIndex> ArgTypeIndices = None; 15783ca95b02SDimitry Andric if (!ReturnAndArgTypeIndices.empty()) { 15793ca95b02SDimitry Andric auto ReturnAndArgTypesRef = makeArrayRef(ReturnAndArgTypeIndices); 15803ca95b02SDimitry Andric ReturnTypeIndex = ReturnAndArgTypesRef.front(); 15813ca95b02SDimitry Andric ArgTypeIndices = ReturnAndArgTypesRef.drop_front(); 15823ca95b02SDimitry Andric } 15833ca95b02SDimitry Andric 15843ca95b02SDimitry Andric ArgListRecord ArgListRec(TypeRecordKind::ArgList, ArgTypeIndices); 15852cab237bSDimitry Andric TypeIndex ArgListIndex = TypeTable.writeLeafType(ArgListRec); 15863ca95b02SDimitry Andric 15873ca95b02SDimitry Andric CallingConvention CC = dwarfCCToCodeView(Ty->getCC()); 15883ca95b02SDimitry Andric 15893ca95b02SDimitry Andric ProcedureRecord Procedure(ReturnTypeIndex, CC, FunctionOptions::None, 15903ca95b02SDimitry Andric ArgTypeIndices.size(), ArgListIndex); 15912cab237bSDimitry Andric return TypeTable.writeLeafType(Procedure); 15923ca95b02SDimitry Andric } 15933ca95b02SDimitry Andric 15943ca95b02SDimitry Andric TypeIndex CodeViewDebug::lowerTypeMemberFunction(const DISubroutineType *Ty, 15953ca95b02SDimitry Andric const DIType *ClassTy, 15962cab237bSDimitry Andric int ThisAdjustment, 15972cab237bSDimitry Andric bool IsStaticMethod) { 15983ca95b02SDimitry Andric // Lower the containing class type. 15993ca95b02SDimitry Andric TypeIndex ClassType = getTypeIndex(ClassTy); 16003ca95b02SDimitry Andric 16013ca95b02SDimitry Andric SmallVector<TypeIndex, 8> ReturnAndArgTypeIndices; 16023ca95b02SDimitry Andric for (DITypeRef ArgTypeRef : Ty->getTypeArray()) 16033ca95b02SDimitry Andric ReturnAndArgTypeIndices.push_back(getTypeIndex(ArgTypeRef)); 16043ca95b02SDimitry Andric 16053ca95b02SDimitry Andric TypeIndex ReturnTypeIndex = TypeIndex::Void(); 16063ca95b02SDimitry Andric ArrayRef<TypeIndex> ArgTypeIndices = None; 16073ca95b02SDimitry Andric if (!ReturnAndArgTypeIndices.empty()) { 16083ca95b02SDimitry Andric auto ReturnAndArgTypesRef = makeArrayRef(ReturnAndArgTypeIndices); 16093ca95b02SDimitry Andric ReturnTypeIndex = ReturnAndArgTypesRef.front(); 16103ca95b02SDimitry Andric ArgTypeIndices = ReturnAndArgTypesRef.drop_front(); 16113ca95b02SDimitry Andric } 16122cab237bSDimitry Andric TypeIndex ThisTypeIndex; 16132cab237bSDimitry Andric if (!IsStaticMethod && !ArgTypeIndices.empty()) { 16143ca95b02SDimitry Andric ThisTypeIndex = ArgTypeIndices.front(); 16153ca95b02SDimitry Andric ArgTypeIndices = ArgTypeIndices.drop_front(); 16163ca95b02SDimitry Andric } 16173ca95b02SDimitry Andric 16183ca95b02SDimitry Andric ArgListRecord ArgListRec(TypeRecordKind::ArgList, ArgTypeIndices); 16192cab237bSDimitry Andric TypeIndex ArgListIndex = TypeTable.writeLeafType(ArgListRec); 16203ca95b02SDimitry Andric 16213ca95b02SDimitry Andric CallingConvention CC = dwarfCCToCodeView(Ty->getCC()); 16223ca95b02SDimitry Andric 16232cab237bSDimitry Andric // TODO: Need to use the correct values for FunctionOptions. 1624d88c1a5aSDimitry Andric MemberFunctionRecord MFR(ReturnTypeIndex, ClassType, ThisTypeIndex, CC, 1625d88c1a5aSDimitry Andric FunctionOptions::None, ArgTypeIndices.size(), 1626d88c1a5aSDimitry Andric ArgListIndex, ThisAdjustment); 16272cab237bSDimitry Andric return TypeTable.writeLeafType(MFR); 16283ca95b02SDimitry Andric } 16293ca95b02SDimitry Andric 1630d88c1a5aSDimitry Andric TypeIndex CodeViewDebug::lowerTypeVFTableShape(const DIDerivedType *Ty) { 16316bc11b14SDimitry Andric unsigned VSlotCount = 16326bc11b14SDimitry Andric Ty->getSizeInBits() / (8 * Asm->MAI->getCodePointerSize()); 1633d88c1a5aSDimitry Andric SmallVector<VFTableSlotKind, 4> Slots(VSlotCount, VFTableSlotKind::Near); 1634d88c1a5aSDimitry Andric 1635d88c1a5aSDimitry Andric VFTableShapeRecord VFTSR(Slots); 16362cab237bSDimitry Andric return TypeTable.writeLeafType(VFTSR); 1637d88c1a5aSDimitry Andric } 1638d88c1a5aSDimitry Andric 16393ca95b02SDimitry Andric static MemberAccess translateAccessFlags(unsigned RecordTag, unsigned Flags) { 16403ca95b02SDimitry Andric switch (Flags & DINode::FlagAccessibility) { 16413ca95b02SDimitry Andric case DINode::FlagPrivate: return MemberAccess::Private; 16423ca95b02SDimitry Andric case DINode::FlagPublic: return MemberAccess::Public; 16433ca95b02SDimitry Andric case DINode::FlagProtected: return MemberAccess::Protected; 16443ca95b02SDimitry Andric case 0: 16453ca95b02SDimitry Andric // If there was no explicit access control, provide the default for the tag. 16463ca95b02SDimitry Andric return RecordTag == dwarf::DW_TAG_class_type ? MemberAccess::Private 16473ca95b02SDimitry Andric : MemberAccess::Public; 16483ca95b02SDimitry Andric } 16493ca95b02SDimitry Andric llvm_unreachable("access flags are exclusive"); 16503ca95b02SDimitry Andric } 16513ca95b02SDimitry Andric 16523ca95b02SDimitry Andric static MethodOptions translateMethodOptionFlags(const DISubprogram *SP) { 16533ca95b02SDimitry Andric if (SP->isArtificial()) 16543ca95b02SDimitry Andric return MethodOptions::CompilerGenerated; 16553ca95b02SDimitry Andric 16563ca95b02SDimitry Andric // FIXME: Handle other MethodOptions. 16573ca95b02SDimitry Andric 16583ca95b02SDimitry Andric return MethodOptions::None; 16593ca95b02SDimitry Andric } 16603ca95b02SDimitry Andric 16613ca95b02SDimitry Andric static MethodKind translateMethodKindFlags(const DISubprogram *SP, 16623ca95b02SDimitry Andric bool Introduced) { 16632cab237bSDimitry Andric if (SP->getFlags() & DINode::FlagStaticMember) 16642cab237bSDimitry Andric return MethodKind::Static; 16652cab237bSDimitry Andric 16663ca95b02SDimitry Andric switch (SP->getVirtuality()) { 16673ca95b02SDimitry Andric case dwarf::DW_VIRTUALITY_none: 16683ca95b02SDimitry Andric break; 16693ca95b02SDimitry Andric case dwarf::DW_VIRTUALITY_virtual: 16703ca95b02SDimitry Andric return Introduced ? MethodKind::IntroducingVirtual : MethodKind::Virtual; 16713ca95b02SDimitry Andric case dwarf::DW_VIRTUALITY_pure_virtual: 16723ca95b02SDimitry Andric return Introduced ? MethodKind::PureIntroducingVirtual 16733ca95b02SDimitry Andric : MethodKind::PureVirtual; 16743ca95b02SDimitry Andric default: 16753ca95b02SDimitry Andric llvm_unreachable("unhandled virtuality case"); 16763ca95b02SDimitry Andric } 16773ca95b02SDimitry Andric 16783ca95b02SDimitry Andric return MethodKind::Vanilla; 16793ca95b02SDimitry Andric } 16803ca95b02SDimitry Andric 16813ca95b02SDimitry Andric static TypeRecordKind getRecordKind(const DICompositeType *Ty) { 16823ca95b02SDimitry Andric switch (Ty->getTag()) { 16833ca95b02SDimitry Andric case dwarf::DW_TAG_class_type: return TypeRecordKind::Class; 16843ca95b02SDimitry Andric case dwarf::DW_TAG_structure_type: return TypeRecordKind::Struct; 16853ca95b02SDimitry Andric } 16863ca95b02SDimitry Andric llvm_unreachable("unexpected tag"); 16873ca95b02SDimitry Andric } 16883ca95b02SDimitry Andric 16893ca95b02SDimitry Andric /// Return ClassOptions that should be present on both the forward declaration 16903ca95b02SDimitry Andric /// and the defintion of a tag type. 16913ca95b02SDimitry Andric static ClassOptions getCommonClassOptions(const DICompositeType *Ty) { 16923ca95b02SDimitry Andric ClassOptions CO = ClassOptions::None; 16933ca95b02SDimitry Andric 16943ca95b02SDimitry Andric // MSVC always sets this flag, even for local types. Clang doesn't always 16953ca95b02SDimitry Andric // appear to give every type a linkage name, which may be problematic for us. 16963ca95b02SDimitry Andric // FIXME: Investigate the consequences of not following them here. 16973ca95b02SDimitry Andric if (!Ty->getIdentifier().empty()) 16983ca95b02SDimitry Andric CO |= ClassOptions::HasUniqueName; 16993ca95b02SDimitry Andric 17003ca95b02SDimitry Andric // Put the Nested flag on a type if it appears immediately inside a tag type. 17013ca95b02SDimitry Andric // Do not walk the scope chain. Do not attempt to compute ContainsNestedClass 17023ca95b02SDimitry Andric // here. That flag is only set on definitions, and not forward declarations. 17033ca95b02SDimitry Andric const DIScope *ImmediateScope = Ty->getScope().resolve(); 17043ca95b02SDimitry Andric if (ImmediateScope && isa<DICompositeType>(ImmediateScope)) 17053ca95b02SDimitry Andric CO |= ClassOptions::Nested; 17063ca95b02SDimitry Andric 17073ca95b02SDimitry Andric // Put the Scoped flag on function-local types. 17083ca95b02SDimitry Andric for (const DIScope *Scope = ImmediateScope; Scope != nullptr; 17093ca95b02SDimitry Andric Scope = Scope->getScope().resolve()) { 17103ca95b02SDimitry Andric if (isa<DISubprogram>(Scope)) { 17113ca95b02SDimitry Andric CO |= ClassOptions::Scoped; 17123ca95b02SDimitry Andric break; 17133ca95b02SDimitry Andric } 17143ca95b02SDimitry Andric } 17153ca95b02SDimitry Andric 17163ca95b02SDimitry Andric return CO; 17173ca95b02SDimitry Andric } 17183ca95b02SDimitry Andric 17193ca95b02SDimitry Andric TypeIndex CodeViewDebug::lowerTypeEnum(const DICompositeType *Ty) { 17203ca95b02SDimitry Andric ClassOptions CO = getCommonClassOptions(Ty); 17213ca95b02SDimitry Andric TypeIndex FTI; 17223ca95b02SDimitry Andric unsigned EnumeratorCount = 0; 17233ca95b02SDimitry Andric 17243ca95b02SDimitry Andric if (Ty->isForwardDecl()) { 17253ca95b02SDimitry Andric CO |= ClassOptions::ForwardReference; 17263ca95b02SDimitry Andric } else { 17272cab237bSDimitry Andric ContinuationRecordBuilder ContinuationBuilder; 17282cab237bSDimitry Andric ContinuationBuilder.begin(ContinuationRecordKind::FieldList); 17293ca95b02SDimitry Andric for (const DINode *Element : Ty->getElements()) { 17303ca95b02SDimitry Andric // We assume that the frontend provides all members in source declaration 17313ca95b02SDimitry Andric // order, which is what MSVC does. 17323ca95b02SDimitry Andric if (auto *Enumerator = dyn_cast_or_null<DIEnumerator>(Element)) { 1733d88c1a5aSDimitry Andric EnumeratorRecord ER(MemberAccess::Public, 1734d88c1a5aSDimitry Andric APSInt::getUnsigned(Enumerator->getValue()), 1735d88c1a5aSDimitry Andric Enumerator->getName()); 17362cab237bSDimitry Andric ContinuationBuilder.writeMemberType(ER); 17373ca95b02SDimitry Andric EnumeratorCount++; 17383ca95b02SDimitry Andric } 17393ca95b02SDimitry Andric } 17402cab237bSDimitry Andric FTI = TypeTable.insertRecord(ContinuationBuilder); 17413ca95b02SDimitry Andric } 17423ca95b02SDimitry Andric 17433ca95b02SDimitry Andric std::string FullName = getFullyQualifiedName(Ty); 17443ca95b02SDimitry Andric 1745d88c1a5aSDimitry Andric EnumRecord ER(EnumeratorCount, CO, FTI, FullName, Ty->getIdentifier(), 1746d88c1a5aSDimitry Andric getTypeIndex(Ty->getBaseType())); 17472cab237bSDimitry Andric return TypeTable.writeLeafType(ER); 17483ca95b02SDimitry Andric } 17493ca95b02SDimitry Andric 17503ca95b02SDimitry Andric //===----------------------------------------------------------------------===// 17513ca95b02SDimitry Andric // ClassInfo 17523ca95b02SDimitry Andric //===----------------------------------------------------------------------===// 17533ca95b02SDimitry Andric 17543ca95b02SDimitry Andric struct llvm::ClassInfo { 17553ca95b02SDimitry Andric struct MemberInfo { 17563ca95b02SDimitry Andric const DIDerivedType *MemberTypeNode; 17573ca95b02SDimitry Andric uint64_t BaseOffset; 17583ca95b02SDimitry Andric }; 17593ca95b02SDimitry Andric // [MemberInfo] 1760db17bf38SDimitry Andric using MemberList = std::vector<MemberInfo>; 17613ca95b02SDimitry Andric 1762db17bf38SDimitry Andric using MethodsList = TinyPtrVector<const DISubprogram *>; 17633ca95b02SDimitry Andric // MethodName -> MethodsList 1764db17bf38SDimitry Andric using MethodsMap = MapVector<MDString *, MethodsList>; 17653ca95b02SDimitry Andric 17663ca95b02SDimitry Andric /// Base classes. 17673ca95b02SDimitry Andric std::vector<const DIDerivedType *> Inheritance; 17683ca95b02SDimitry Andric 17693ca95b02SDimitry Andric /// Direct members. 17703ca95b02SDimitry Andric MemberList Members; 17713ca95b02SDimitry Andric // Direct overloaded methods gathered by name. 17723ca95b02SDimitry Andric MethodsMap Methods; 17733ca95b02SDimitry Andric 1774d88c1a5aSDimitry Andric TypeIndex VShapeTI; 1775d88c1a5aSDimitry Andric 17762cab237bSDimitry Andric std::vector<const DIType *> NestedTypes; 17773ca95b02SDimitry Andric }; 17783ca95b02SDimitry Andric 17793ca95b02SDimitry Andric void CodeViewDebug::clear() { 17803ca95b02SDimitry Andric assert(CurFn == nullptr); 17813ca95b02SDimitry Andric FileIdMap.clear(); 17823ca95b02SDimitry Andric FnDebugInfo.clear(); 17833ca95b02SDimitry Andric FileToFilepathMap.clear(); 17843ca95b02SDimitry Andric LocalUDTs.clear(); 17853ca95b02SDimitry Andric GlobalUDTs.clear(); 17863ca95b02SDimitry Andric TypeIndices.clear(); 17873ca95b02SDimitry Andric CompleteTypeIndices.clear(); 17883ca95b02SDimitry Andric } 17893ca95b02SDimitry Andric 17903ca95b02SDimitry Andric void CodeViewDebug::collectMemberInfo(ClassInfo &Info, 17913ca95b02SDimitry Andric const DIDerivedType *DDTy) { 17923ca95b02SDimitry Andric if (!DDTy->getName().empty()) { 17933ca95b02SDimitry Andric Info.Members.push_back({DDTy, 0}); 17943ca95b02SDimitry Andric return; 17953ca95b02SDimitry Andric } 17963ca95b02SDimitry Andric // An unnamed member must represent a nested struct or union. Add all the 17973ca95b02SDimitry Andric // indirect fields to the current record. 17983ca95b02SDimitry Andric assert((DDTy->getOffsetInBits() % 8) == 0 && "Unnamed bitfield member!"); 17993ca95b02SDimitry Andric uint64_t Offset = DDTy->getOffsetInBits(); 18003ca95b02SDimitry Andric const DIType *Ty = DDTy->getBaseType().resolve(); 18013ca95b02SDimitry Andric const DICompositeType *DCTy = cast<DICompositeType>(Ty); 18023ca95b02SDimitry Andric ClassInfo NestedInfo = collectClassInfo(DCTy); 18033ca95b02SDimitry Andric for (const ClassInfo::MemberInfo &IndirectField : NestedInfo.Members) 18043ca95b02SDimitry Andric Info.Members.push_back( 18053ca95b02SDimitry Andric {IndirectField.MemberTypeNode, IndirectField.BaseOffset + Offset}); 18063ca95b02SDimitry Andric } 18073ca95b02SDimitry Andric 18083ca95b02SDimitry Andric ClassInfo CodeViewDebug::collectClassInfo(const DICompositeType *Ty) { 18093ca95b02SDimitry Andric ClassInfo Info; 18103ca95b02SDimitry Andric // Add elements to structure type. 18113ca95b02SDimitry Andric DINodeArray Elements = Ty->getElements(); 18123ca95b02SDimitry Andric for (auto *Element : Elements) { 18133ca95b02SDimitry Andric // We assume that the frontend provides all members in source declaration 18143ca95b02SDimitry Andric // order, which is what MSVC does. 18153ca95b02SDimitry Andric if (!Element) 18163ca95b02SDimitry Andric continue; 18173ca95b02SDimitry Andric if (auto *SP = dyn_cast<DISubprogram>(Element)) { 18183ca95b02SDimitry Andric Info.Methods[SP->getRawName()].push_back(SP); 18193ca95b02SDimitry Andric } else if (auto *DDTy = dyn_cast<DIDerivedType>(Element)) { 18203ca95b02SDimitry Andric if (DDTy->getTag() == dwarf::DW_TAG_member) { 18213ca95b02SDimitry Andric collectMemberInfo(Info, DDTy); 18223ca95b02SDimitry Andric } else if (DDTy->getTag() == dwarf::DW_TAG_inheritance) { 18233ca95b02SDimitry Andric Info.Inheritance.push_back(DDTy); 1824d88c1a5aSDimitry Andric } else if (DDTy->getTag() == dwarf::DW_TAG_pointer_type && 1825d88c1a5aSDimitry Andric DDTy->getName() == "__vtbl_ptr_type") { 1826d88c1a5aSDimitry Andric Info.VShapeTI = getTypeIndex(DDTy); 18272cab237bSDimitry Andric } else if (DDTy->getTag() == dwarf::DW_TAG_typedef) { 18282cab237bSDimitry Andric Info.NestedTypes.push_back(DDTy); 18293ca95b02SDimitry Andric } else if (DDTy->getTag() == dwarf::DW_TAG_friend) { 18303ca95b02SDimitry Andric // Ignore friend members. It appears that MSVC emitted info about 18313ca95b02SDimitry Andric // friends in the past, but modern versions do not. 18323ca95b02SDimitry Andric } 18333ca95b02SDimitry Andric } else if (auto *Composite = dyn_cast<DICompositeType>(Element)) { 18342cab237bSDimitry Andric Info.NestedTypes.push_back(Composite); 18353ca95b02SDimitry Andric } 18363ca95b02SDimitry Andric // Skip other unrecognized kinds of elements. 18373ca95b02SDimitry Andric } 18383ca95b02SDimitry Andric return Info; 18393ca95b02SDimitry Andric } 18403ca95b02SDimitry Andric 18413ca95b02SDimitry Andric TypeIndex CodeViewDebug::lowerTypeClass(const DICompositeType *Ty) { 18423ca95b02SDimitry Andric // First, construct the forward decl. Don't look into Ty to compute the 18433ca95b02SDimitry Andric // forward decl options, since it might not be available in all TUs. 18443ca95b02SDimitry Andric TypeRecordKind Kind = getRecordKind(Ty); 18453ca95b02SDimitry Andric ClassOptions CO = 18463ca95b02SDimitry Andric ClassOptions::ForwardReference | getCommonClassOptions(Ty); 18473ca95b02SDimitry Andric std::string FullName = getFullyQualifiedName(Ty); 1848d88c1a5aSDimitry Andric ClassRecord CR(Kind, 0, CO, TypeIndex(), TypeIndex(), TypeIndex(), 0, 1849d88c1a5aSDimitry Andric FullName, Ty->getIdentifier()); 18502cab237bSDimitry Andric TypeIndex FwdDeclTI = TypeTable.writeLeafType(CR); 18513ca95b02SDimitry Andric if (!Ty->isForwardDecl()) 18523ca95b02SDimitry Andric DeferredCompleteTypes.push_back(Ty); 18533ca95b02SDimitry Andric return FwdDeclTI; 18543ca95b02SDimitry Andric } 18553ca95b02SDimitry Andric 18563ca95b02SDimitry Andric TypeIndex CodeViewDebug::lowerCompleteTypeClass(const DICompositeType *Ty) { 18573ca95b02SDimitry Andric // Construct the field list and complete type record. 18583ca95b02SDimitry Andric TypeRecordKind Kind = getRecordKind(Ty); 18593ca95b02SDimitry Andric ClassOptions CO = getCommonClassOptions(Ty); 18603ca95b02SDimitry Andric TypeIndex FieldTI; 18613ca95b02SDimitry Andric TypeIndex VShapeTI; 18623ca95b02SDimitry Andric unsigned FieldCount; 18633ca95b02SDimitry Andric bool ContainsNestedClass; 18643ca95b02SDimitry Andric std::tie(FieldTI, VShapeTI, FieldCount, ContainsNestedClass) = 18653ca95b02SDimitry Andric lowerRecordFieldList(Ty); 18663ca95b02SDimitry Andric 18673ca95b02SDimitry Andric if (ContainsNestedClass) 18683ca95b02SDimitry Andric CO |= ClassOptions::ContainsNestedClass; 18693ca95b02SDimitry Andric 18703ca95b02SDimitry Andric std::string FullName = getFullyQualifiedName(Ty); 18713ca95b02SDimitry Andric 18723ca95b02SDimitry Andric uint64_t SizeInBytes = Ty->getSizeInBits() / 8; 18733ca95b02SDimitry Andric 1874d88c1a5aSDimitry Andric ClassRecord CR(Kind, FieldCount, CO, FieldTI, TypeIndex(), VShapeTI, 1875d88c1a5aSDimitry Andric SizeInBytes, FullName, Ty->getIdentifier()); 18762cab237bSDimitry Andric TypeIndex ClassTI = TypeTable.writeLeafType(CR); 18773ca95b02SDimitry Andric 18780f5676f4SDimitry Andric if (const auto *File = Ty->getFile()) { 18790f5676f4SDimitry Andric StringIdRecord SIDR(TypeIndex(0x0), getFullFilepath(File)); 18802cab237bSDimitry Andric TypeIndex SIDI = TypeTable.writeLeafType(SIDR); 18812cab237bSDimitry Andric 1882d88c1a5aSDimitry Andric UdtSourceLineRecord USLR(ClassTI, SIDI, Ty->getLine()); 18832cab237bSDimitry Andric TypeTable.writeLeafType(USLR); 18840f5676f4SDimitry Andric } 18853ca95b02SDimitry Andric 18862cab237bSDimitry Andric addToUDTs(Ty); 18873ca95b02SDimitry Andric 18883ca95b02SDimitry Andric return ClassTI; 18893ca95b02SDimitry Andric } 18903ca95b02SDimitry Andric 18913ca95b02SDimitry Andric TypeIndex CodeViewDebug::lowerTypeUnion(const DICompositeType *Ty) { 18923ca95b02SDimitry Andric ClassOptions CO = 18933ca95b02SDimitry Andric ClassOptions::ForwardReference | getCommonClassOptions(Ty); 18943ca95b02SDimitry Andric std::string FullName = getFullyQualifiedName(Ty); 1895d88c1a5aSDimitry Andric UnionRecord UR(0, CO, TypeIndex(), 0, FullName, Ty->getIdentifier()); 18962cab237bSDimitry Andric TypeIndex FwdDeclTI = TypeTable.writeLeafType(UR); 18973ca95b02SDimitry Andric if (!Ty->isForwardDecl()) 18983ca95b02SDimitry Andric DeferredCompleteTypes.push_back(Ty); 18993ca95b02SDimitry Andric return FwdDeclTI; 19003ca95b02SDimitry Andric } 19013ca95b02SDimitry Andric 19023ca95b02SDimitry Andric TypeIndex CodeViewDebug::lowerCompleteTypeUnion(const DICompositeType *Ty) { 19033ca95b02SDimitry Andric ClassOptions CO = ClassOptions::Sealed | getCommonClassOptions(Ty); 19043ca95b02SDimitry Andric TypeIndex FieldTI; 19053ca95b02SDimitry Andric unsigned FieldCount; 19063ca95b02SDimitry Andric bool ContainsNestedClass; 19073ca95b02SDimitry Andric std::tie(FieldTI, std::ignore, FieldCount, ContainsNestedClass) = 19083ca95b02SDimitry Andric lowerRecordFieldList(Ty); 19093ca95b02SDimitry Andric 19103ca95b02SDimitry Andric if (ContainsNestedClass) 19113ca95b02SDimitry Andric CO |= ClassOptions::ContainsNestedClass; 19123ca95b02SDimitry Andric 19133ca95b02SDimitry Andric uint64_t SizeInBytes = Ty->getSizeInBits() / 8; 19143ca95b02SDimitry Andric std::string FullName = getFullyQualifiedName(Ty); 19153ca95b02SDimitry Andric 1916d88c1a5aSDimitry Andric UnionRecord UR(FieldCount, CO, FieldTI, SizeInBytes, FullName, 1917d88c1a5aSDimitry Andric Ty->getIdentifier()); 19182cab237bSDimitry Andric TypeIndex UnionTI = TypeTable.writeLeafType(UR); 19193ca95b02SDimitry Andric 1920d88c1a5aSDimitry Andric StringIdRecord SIR(TypeIndex(0x0), getFullFilepath(Ty->getFile())); 19212cab237bSDimitry Andric TypeIndex SIRI = TypeTable.writeLeafType(SIR); 19223ca95b02SDimitry Andric 19232cab237bSDimitry Andric UdtSourceLineRecord USLR(UnionTI, SIRI, Ty->getLine()); 19242cab237bSDimitry Andric TypeTable.writeLeafType(USLR); 19252cab237bSDimitry Andric 19262cab237bSDimitry Andric addToUDTs(Ty); 19273ca95b02SDimitry Andric 19283ca95b02SDimitry Andric return UnionTI; 19293ca95b02SDimitry Andric } 19303ca95b02SDimitry Andric 19313ca95b02SDimitry Andric std::tuple<TypeIndex, TypeIndex, unsigned, bool> 19323ca95b02SDimitry Andric CodeViewDebug::lowerRecordFieldList(const DICompositeType *Ty) { 19333ca95b02SDimitry Andric // Manually count members. MSVC appears to count everything that generates a 19343ca95b02SDimitry Andric // field list record. Each individual overload in a method overload group 19353ca95b02SDimitry Andric // contributes to this count, even though the overload group is a single field 19363ca95b02SDimitry Andric // list record. 19373ca95b02SDimitry Andric unsigned MemberCount = 0; 19383ca95b02SDimitry Andric ClassInfo Info = collectClassInfo(Ty); 19392cab237bSDimitry Andric ContinuationRecordBuilder ContinuationBuilder; 19402cab237bSDimitry Andric ContinuationBuilder.begin(ContinuationRecordKind::FieldList); 19413ca95b02SDimitry Andric 19423ca95b02SDimitry Andric // Create base classes. 19433ca95b02SDimitry Andric for (const DIDerivedType *I : Info.Inheritance) { 19443ca95b02SDimitry Andric if (I->getFlags() & DINode::FlagVirtual) { 19453ca95b02SDimitry Andric // Virtual base. 19463ca95b02SDimitry Andric // FIXME: Emit VBPtrOffset when the frontend provides it. 19473ca95b02SDimitry Andric unsigned VBPtrOffset = 0; 19483ca95b02SDimitry Andric // FIXME: Despite the accessor name, the offset is really in bytes. 19493ca95b02SDimitry Andric unsigned VBTableIndex = I->getOffsetInBits() / 4; 1950d88c1a5aSDimitry Andric auto RecordKind = (I->getFlags() & DINode::FlagIndirectVirtualBase) == DINode::FlagIndirectVirtualBase 1951d88c1a5aSDimitry Andric ? TypeRecordKind::IndirectVirtualBaseClass 1952d88c1a5aSDimitry Andric : TypeRecordKind::VirtualBaseClass; 1953d88c1a5aSDimitry Andric VirtualBaseClassRecord VBCR( 1954d88c1a5aSDimitry Andric RecordKind, translateAccessFlags(Ty->getTag(), I->getFlags()), 19553ca95b02SDimitry Andric getTypeIndex(I->getBaseType()), getVBPTypeIndex(), VBPtrOffset, 1956d88c1a5aSDimitry Andric VBTableIndex); 1957d88c1a5aSDimitry Andric 19582cab237bSDimitry Andric ContinuationBuilder.writeMemberType(VBCR); 19593ca95b02SDimitry Andric } else { 19603ca95b02SDimitry Andric assert(I->getOffsetInBits() % 8 == 0 && 19613ca95b02SDimitry Andric "bases must be on byte boundaries"); 1962d88c1a5aSDimitry Andric BaseClassRecord BCR(translateAccessFlags(Ty->getTag(), I->getFlags()), 1963d88c1a5aSDimitry Andric getTypeIndex(I->getBaseType()), 1964d88c1a5aSDimitry Andric I->getOffsetInBits() / 8); 19652cab237bSDimitry Andric ContinuationBuilder.writeMemberType(BCR); 19663ca95b02SDimitry Andric } 19673ca95b02SDimitry Andric } 19683ca95b02SDimitry Andric 19693ca95b02SDimitry Andric // Create members. 19703ca95b02SDimitry Andric for (ClassInfo::MemberInfo &MemberInfo : Info.Members) { 19713ca95b02SDimitry Andric const DIDerivedType *Member = MemberInfo.MemberTypeNode; 19723ca95b02SDimitry Andric TypeIndex MemberBaseType = getTypeIndex(Member->getBaseType()); 19733ca95b02SDimitry Andric StringRef MemberName = Member->getName(); 19743ca95b02SDimitry Andric MemberAccess Access = 19753ca95b02SDimitry Andric translateAccessFlags(Ty->getTag(), Member->getFlags()); 19763ca95b02SDimitry Andric 19773ca95b02SDimitry Andric if (Member->isStaticMember()) { 1978d88c1a5aSDimitry Andric StaticDataMemberRecord SDMR(Access, MemberBaseType, MemberName); 19792cab237bSDimitry Andric ContinuationBuilder.writeMemberType(SDMR); 1980d88c1a5aSDimitry Andric MemberCount++; 1981d88c1a5aSDimitry Andric continue; 1982d88c1a5aSDimitry Andric } 1983d88c1a5aSDimitry Andric 1984d88c1a5aSDimitry Andric // Virtual function pointer member. 1985d88c1a5aSDimitry Andric if ((Member->getFlags() & DINode::FlagArtificial) && 1986d88c1a5aSDimitry Andric Member->getName().startswith("_vptr$")) { 1987d88c1a5aSDimitry Andric VFPtrRecord VFPR(getTypeIndex(Member->getBaseType())); 19882cab237bSDimitry Andric ContinuationBuilder.writeMemberType(VFPR); 19893ca95b02SDimitry Andric MemberCount++; 19903ca95b02SDimitry Andric continue; 19913ca95b02SDimitry Andric } 19923ca95b02SDimitry Andric 19933ca95b02SDimitry Andric // Data member. 19943ca95b02SDimitry Andric uint64_t MemberOffsetInBits = 19953ca95b02SDimitry Andric Member->getOffsetInBits() + MemberInfo.BaseOffset; 19963ca95b02SDimitry Andric if (Member->isBitField()) { 19973ca95b02SDimitry Andric uint64_t StartBitOffset = MemberOffsetInBits; 19983ca95b02SDimitry Andric if (const auto *CI = 19993ca95b02SDimitry Andric dyn_cast_or_null<ConstantInt>(Member->getStorageOffsetInBits())) { 20003ca95b02SDimitry Andric MemberOffsetInBits = CI->getZExtValue() + MemberInfo.BaseOffset; 20013ca95b02SDimitry Andric } 20023ca95b02SDimitry Andric StartBitOffset -= MemberOffsetInBits; 2003d88c1a5aSDimitry Andric BitFieldRecord BFR(MemberBaseType, Member->getSizeInBits(), 2004d88c1a5aSDimitry Andric StartBitOffset); 20052cab237bSDimitry Andric MemberBaseType = TypeTable.writeLeafType(BFR); 20063ca95b02SDimitry Andric } 20073ca95b02SDimitry Andric uint64_t MemberOffsetInBytes = MemberOffsetInBits / 8; 2008d88c1a5aSDimitry Andric DataMemberRecord DMR(Access, MemberBaseType, MemberOffsetInBytes, 2009d88c1a5aSDimitry Andric MemberName); 20102cab237bSDimitry Andric ContinuationBuilder.writeMemberType(DMR); 20113ca95b02SDimitry Andric MemberCount++; 20123ca95b02SDimitry Andric } 20133ca95b02SDimitry Andric 20143ca95b02SDimitry Andric // Create methods 20153ca95b02SDimitry Andric for (auto &MethodItr : Info.Methods) { 20163ca95b02SDimitry Andric StringRef Name = MethodItr.first->getString(); 20173ca95b02SDimitry Andric 20183ca95b02SDimitry Andric std::vector<OneMethodRecord> Methods; 20193ca95b02SDimitry Andric for (const DISubprogram *SP : MethodItr.second) { 20203ca95b02SDimitry Andric TypeIndex MethodType = getMemberFunctionType(SP, Ty); 20213ca95b02SDimitry Andric bool Introduced = SP->getFlags() & DINode::FlagIntroducedVirtual; 20223ca95b02SDimitry Andric 20233ca95b02SDimitry Andric unsigned VFTableOffset = -1; 20243ca95b02SDimitry Andric if (Introduced) 20253ca95b02SDimitry Andric VFTableOffset = SP->getVirtualIndex() * getPointerSizeInBytes(); 20263ca95b02SDimitry Andric 2027d88c1a5aSDimitry Andric Methods.push_back(OneMethodRecord( 2028d88c1a5aSDimitry Andric MethodType, translateAccessFlags(Ty->getTag(), SP->getFlags()), 2029d88c1a5aSDimitry Andric translateMethodKindFlags(SP, Introduced), 2030d88c1a5aSDimitry Andric translateMethodOptionFlags(SP), VFTableOffset, Name)); 20313ca95b02SDimitry Andric MemberCount++; 20323ca95b02SDimitry Andric } 2033db17bf38SDimitry Andric assert(!Methods.empty() && "Empty methods map entry"); 20343ca95b02SDimitry Andric if (Methods.size() == 1) 20352cab237bSDimitry Andric ContinuationBuilder.writeMemberType(Methods[0]); 20363ca95b02SDimitry Andric else { 20372cab237bSDimitry Andric // FIXME: Make this use its own ContinuationBuilder so that 20382cab237bSDimitry Andric // MethodOverloadList can be split correctly. 2039d88c1a5aSDimitry Andric MethodOverloadListRecord MOLR(Methods); 20402cab237bSDimitry Andric TypeIndex MethodList = TypeTable.writeLeafType(MOLR); 20412cab237bSDimitry Andric 2042d88c1a5aSDimitry Andric OverloadedMethodRecord OMR(Methods.size(), MethodList, Name); 20432cab237bSDimitry Andric ContinuationBuilder.writeMemberType(OMR); 20443ca95b02SDimitry Andric } 20453ca95b02SDimitry Andric } 20463ca95b02SDimitry Andric 20473ca95b02SDimitry Andric // Create nested classes. 20482cab237bSDimitry Andric for (const DIType *Nested : Info.NestedTypes) { 20493ca95b02SDimitry Andric NestedTypeRecord R(getTypeIndex(DITypeRef(Nested)), Nested->getName()); 20502cab237bSDimitry Andric ContinuationBuilder.writeMemberType(R); 20513ca95b02SDimitry Andric MemberCount++; 20523ca95b02SDimitry Andric } 20533ca95b02SDimitry Andric 20542cab237bSDimitry Andric TypeIndex FieldTI = TypeTable.insertRecord(ContinuationBuilder); 2055d88c1a5aSDimitry Andric return std::make_tuple(FieldTI, Info.VShapeTI, MemberCount, 20562cab237bSDimitry Andric !Info.NestedTypes.empty()); 20573ca95b02SDimitry Andric } 20583ca95b02SDimitry Andric 20593ca95b02SDimitry Andric TypeIndex CodeViewDebug::getVBPTypeIndex() { 20603ca95b02SDimitry Andric if (!VBPType.getIndex()) { 20613ca95b02SDimitry Andric // Make a 'const int *' type. 20623ca95b02SDimitry Andric ModifierRecord MR(TypeIndex::Int32(), ModifierOptions::Const); 20632cab237bSDimitry Andric TypeIndex ModifiedTI = TypeTable.writeLeafType(MR); 20643ca95b02SDimitry Andric 20653ca95b02SDimitry Andric PointerKind PK = getPointerSizeInBytes() == 8 ? PointerKind::Near64 20663ca95b02SDimitry Andric : PointerKind::Near32; 20673ca95b02SDimitry Andric PointerMode PM = PointerMode::Pointer; 20683ca95b02SDimitry Andric PointerOptions PO = PointerOptions::None; 20693ca95b02SDimitry Andric PointerRecord PR(ModifiedTI, PK, PM, PO, getPointerSizeInBytes()); 20702cab237bSDimitry Andric VBPType = TypeTable.writeLeafType(PR); 20713ca95b02SDimitry Andric } 20723ca95b02SDimitry Andric 20733ca95b02SDimitry Andric return VBPType; 20743ca95b02SDimitry Andric } 20753ca95b02SDimitry Andric 20763ca95b02SDimitry Andric TypeIndex CodeViewDebug::getTypeIndex(DITypeRef TypeRef, DITypeRef ClassTyRef) { 20773ca95b02SDimitry Andric const DIType *Ty = TypeRef.resolve(); 20783ca95b02SDimitry Andric const DIType *ClassTy = ClassTyRef.resolve(); 20793ca95b02SDimitry Andric 20803ca95b02SDimitry Andric // The null DIType is the void type. Don't try to hash it. 20813ca95b02SDimitry Andric if (!Ty) 20823ca95b02SDimitry Andric return TypeIndex::Void(); 20833ca95b02SDimitry Andric 20843ca95b02SDimitry Andric // Check if we've already translated this type. Don't try to do a 20853ca95b02SDimitry Andric // get-or-create style insertion that caches the hash lookup across the 20863ca95b02SDimitry Andric // lowerType call. It will update the TypeIndices map. 20873ca95b02SDimitry Andric auto I = TypeIndices.find({Ty, ClassTy}); 20883ca95b02SDimitry Andric if (I != TypeIndices.end()) 20893ca95b02SDimitry Andric return I->second; 20903ca95b02SDimitry Andric 20913ca95b02SDimitry Andric TypeLoweringScope S(*this); 20923ca95b02SDimitry Andric TypeIndex TI = lowerType(Ty, ClassTy); 20933ca95b02SDimitry Andric return recordTypeIndexForDINode(Ty, TI, ClassTy); 20943ca95b02SDimitry Andric } 20953ca95b02SDimitry Andric 20962cab237bSDimitry Andric TypeIndex CodeViewDebug::getTypeIndexForReferenceTo(DITypeRef TypeRef) { 20972cab237bSDimitry Andric DIType *Ty = TypeRef.resolve(); 20982cab237bSDimitry Andric PointerRecord PR(getTypeIndex(Ty), 20992cab237bSDimitry Andric getPointerSizeInBytes() == 8 ? PointerKind::Near64 21002cab237bSDimitry Andric : PointerKind::Near32, 21012cab237bSDimitry Andric PointerMode::LValueReference, PointerOptions::None, 21022cab237bSDimitry Andric Ty->getSizeInBits() / 8); 21032cab237bSDimitry Andric return TypeTable.writeLeafType(PR); 21042cab237bSDimitry Andric } 21052cab237bSDimitry Andric 21063ca95b02SDimitry Andric TypeIndex CodeViewDebug::getCompleteTypeIndex(DITypeRef TypeRef) { 21073ca95b02SDimitry Andric const DIType *Ty = TypeRef.resolve(); 21083ca95b02SDimitry Andric 21093ca95b02SDimitry Andric // The null DIType is the void type. Don't try to hash it. 21103ca95b02SDimitry Andric if (!Ty) 21113ca95b02SDimitry Andric return TypeIndex::Void(); 21123ca95b02SDimitry Andric 21133ca95b02SDimitry Andric // If this is a non-record type, the complete type index is the same as the 21143ca95b02SDimitry Andric // normal type index. Just call getTypeIndex. 21153ca95b02SDimitry Andric switch (Ty->getTag()) { 21163ca95b02SDimitry Andric case dwarf::DW_TAG_class_type: 21173ca95b02SDimitry Andric case dwarf::DW_TAG_structure_type: 21183ca95b02SDimitry Andric case dwarf::DW_TAG_union_type: 21193ca95b02SDimitry Andric break; 21203ca95b02SDimitry Andric default: 21213ca95b02SDimitry Andric return getTypeIndex(Ty); 21223ca95b02SDimitry Andric } 21233ca95b02SDimitry Andric 21243ca95b02SDimitry Andric // Check if we've already translated the complete record type. Lowering a 21253ca95b02SDimitry Andric // complete type should never trigger lowering another complete type, so we 21263ca95b02SDimitry Andric // can reuse the hash table lookup result. 21273ca95b02SDimitry Andric const auto *CTy = cast<DICompositeType>(Ty); 21283ca95b02SDimitry Andric auto InsertResult = CompleteTypeIndices.insert({CTy, TypeIndex()}); 21293ca95b02SDimitry Andric if (!InsertResult.second) 21303ca95b02SDimitry Andric return InsertResult.first->second; 21313ca95b02SDimitry Andric 21323ca95b02SDimitry Andric TypeLoweringScope S(*this); 21333ca95b02SDimitry Andric 21343ca95b02SDimitry Andric // Make sure the forward declaration is emitted first. It's unclear if this 21353ca95b02SDimitry Andric // is necessary, but MSVC does it, and we should follow suit until we can show 21363ca95b02SDimitry Andric // otherwise. 21373ca95b02SDimitry Andric TypeIndex FwdDeclTI = getTypeIndex(CTy); 21383ca95b02SDimitry Andric 21393ca95b02SDimitry Andric // Just use the forward decl if we don't have complete type info. This might 21403ca95b02SDimitry Andric // happen if the frontend is using modules and expects the complete definition 21413ca95b02SDimitry Andric // to be emitted elsewhere. 21423ca95b02SDimitry Andric if (CTy->isForwardDecl()) 21433ca95b02SDimitry Andric return FwdDeclTI; 21443ca95b02SDimitry Andric 21453ca95b02SDimitry Andric TypeIndex TI; 21463ca95b02SDimitry Andric switch (CTy->getTag()) { 21473ca95b02SDimitry Andric case dwarf::DW_TAG_class_type: 21483ca95b02SDimitry Andric case dwarf::DW_TAG_structure_type: 21493ca95b02SDimitry Andric TI = lowerCompleteTypeClass(CTy); 21503ca95b02SDimitry Andric break; 21513ca95b02SDimitry Andric case dwarf::DW_TAG_union_type: 21523ca95b02SDimitry Andric TI = lowerCompleteTypeUnion(CTy); 21533ca95b02SDimitry Andric break; 21543ca95b02SDimitry Andric default: 21553ca95b02SDimitry Andric llvm_unreachable("not a record"); 21563ca95b02SDimitry Andric } 21573ca95b02SDimitry Andric 21583ca95b02SDimitry Andric InsertResult.first->second = TI; 21593ca95b02SDimitry Andric return TI; 21603ca95b02SDimitry Andric } 21613ca95b02SDimitry Andric 21623ca95b02SDimitry Andric /// Emit all the deferred complete record types. Try to do this in FIFO order, 21633ca95b02SDimitry Andric /// and do this until fixpoint, as each complete record type typically 21643ca95b02SDimitry Andric /// references 21653ca95b02SDimitry Andric /// many other record types. 21663ca95b02SDimitry Andric void CodeViewDebug::emitDeferredCompleteTypes() { 21673ca95b02SDimitry Andric SmallVector<const DICompositeType *, 4> TypesToEmit; 21683ca95b02SDimitry Andric while (!DeferredCompleteTypes.empty()) { 21693ca95b02SDimitry Andric std::swap(DeferredCompleteTypes, TypesToEmit); 21703ca95b02SDimitry Andric for (const DICompositeType *RecordTy : TypesToEmit) 21713ca95b02SDimitry Andric getCompleteTypeIndex(RecordTy); 21723ca95b02SDimitry Andric TypesToEmit.clear(); 21733ca95b02SDimitry Andric } 21743ca95b02SDimitry Andric } 21753ca95b02SDimitry Andric 21763ca95b02SDimitry Andric void CodeViewDebug::emitLocalVariableList(ArrayRef<LocalVariable> Locals) { 21773ca95b02SDimitry Andric // Get the sorted list of parameters and emit them first. 21783ca95b02SDimitry Andric SmallVector<const LocalVariable *, 6> Params; 21793ca95b02SDimitry Andric for (const LocalVariable &L : Locals) 21803ca95b02SDimitry Andric if (L.DIVar->isParameter()) 21813ca95b02SDimitry Andric Params.push_back(&L); 21823ca95b02SDimitry Andric std::sort(Params.begin(), Params.end(), 21833ca95b02SDimitry Andric [](const LocalVariable *L, const LocalVariable *R) { 21843ca95b02SDimitry Andric return L->DIVar->getArg() < R->DIVar->getArg(); 21853ca95b02SDimitry Andric }); 21863ca95b02SDimitry Andric for (const LocalVariable *L : Params) 21873ca95b02SDimitry Andric emitLocalVariable(*L); 21883ca95b02SDimitry Andric 21893ca95b02SDimitry Andric // Next emit all non-parameters in the order that we found them. 21903ca95b02SDimitry Andric for (const LocalVariable &L : Locals) 21913ca95b02SDimitry Andric if (!L.DIVar->isParameter()) 21923ca95b02SDimitry Andric emitLocalVariable(L); 21933ca95b02SDimitry Andric } 21943ca95b02SDimitry Andric 21953ca95b02SDimitry Andric void CodeViewDebug::emitLocalVariable(const LocalVariable &Var) { 21963ca95b02SDimitry Andric // LocalSym record, see SymbolRecord.h for more info. 21973ca95b02SDimitry Andric MCSymbol *LocalBegin = MMI->getContext().createTempSymbol(), 21983ca95b02SDimitry Andric *LocalEnd = MMI->getContext().createTempSymbol(); 21993ca95b02SDimitry Andric OS.AddComment("Record length"); 22003ca95b02SDimitry Andric OS.emitAbsoluteSymbolDiff(LocalEnd, LocalBegin, 2); 22013ca95b02SDimitry Andric OS.EmitLabel(LocalBegin); 22023ca95b02SDimitry Andric 22033ca95b02SDimitry Andric OS.AddComment("Record kind: S_LOCAL"); 22043ca95b02SDimitry Andric OS.EmitIntValue(unsigned(SymbolKind::S_LOCAL), 2); 22053ca95b02SDimitry Andric 22063ca95b02SDimitry Andric LocalSymFlags Flags = LocalSymFlags::None; 22073ca95b02SDimitry Andric if (Var.DIVar->isParameter()) 22083ca95b02SDimitry Andric Flags |= LocalSymFlags::IsParameter; 22093ca95b02SDimitry Andric if (Var.DefRanges.empty()) 22103ca95b02SDimitry Andric Flags |= LocalSymFlags::IsOptimizedOut; 22113ca95b02SDimitry Andric 22123ca95b02SDimitry Andric OS.AddComment("TypeIndex"); 22132cab237bSDimitry Andric TypeIndex TI = Var.UseReferenceType 22142cab237bSDimitry Andric ? getTypeIndexForReferenceTo(Var.DIVar->getType()) 22152cab237bSDimitry Andric : getCompleteTypeIndex(Var.DIVar->getType()); 22163ca95b02SDimitry Andric OS.EmitIntValue(TI.getIndex(), 4); 22173ca95b02SDimitry Andric OS.AddComment("Flags"); 22183ca95b02SDimitry Andric OS.EmitIntValue(static_cast<uint16_t>(Flags), 2); 22193ca95b02SDimitry Andric // Truncate the name so we won't overflow the record length field. 22203ca95b02SDimitry Andric emitNullTerminatedSymbolName(OS, Var.DIVar->getName()); 22213ca95b02SDimitry Andric OS.EmitLabel(LocalEnd); 22223ca95b02SDimitry Andric 22233ca95b02SDimitry Andric // Calculate the on disk prefix of the appropriate def range record. The 22243ca95b02SDimitry Andric // records and on disk formats are described in SymbolRecords.h. BytePrefix 22253ca95b02SDimitry Andric // should be big enough to hold all forms without memory allocation. 22263ca95b02SDimitry Andric SmallString<20> BytePrefix; 22273ca95b02SDimitry Andric for (const LocalVarDefRange &DefRange : Var.DefRanges) { 22283ca95b02SDimitry Andric BytePrefix.clear(); 22293ca95b02SDimitry Andric if (DefRange.InMemory) { 2230d88c1a5aSDimitry Andric uint16_t RegRelFlags = 0; 2231d88c1a5aSDimitry Andric if (DefRange.IsSubfield) { 2232d88c1a5aSDimitry Andric RegRelFlags = DefRangeRegisterRelSym::IsSubfieldFlag | 2233d88c1a5aSDimitry Andric (DefRange.StructOffset 2234d88c1a5aSDimitry Andric << DefRangeRegisterRelSym::OffsetInParentShift); 2235d88c1a5aSDimitry Andric } 2236d88c1a5aSDimitry Andric DefRangeRegisterRelSym Sym(S_DEFRANGE_REGISTER_REL); 2237d88c1a5aSDimitry Andric Sym.Hdr.Register = DefRange.CVRegister; 2238d88c1a5aSDimitry Andric Sym.Hdr.Flags = RegRelFlags; 2239d88c1a5aSDimitry Andric Sym.Hdr.BasePointerOffset = DefRange.DataOffset; 22403ca95b02SDimitry Andric ulittle16_t SymKind = ulittle16_t(S_DEFRANGE_REGISTER_REL); 22413ca95b02SDimitry Andric BytePrefix += 22423ca95b02SDimitry Andric StringRef(reinterpret_cast<const char *>(&SymKind), sizeof(SymKind)); 22433ca95b02SDimitry Andric BytePrefix += 2244d88c1a5aSDimitry Andric StringRef(reinterpret_cast<const char *>(&Sym.Hdr), sizeof(Sym.Hdr)); 22453ca95b02SDimitry Andric } else { 22463ca95b02SDimitry Andric assert(DefRange.DataOffset == 0 && "unexpected offset into register"); 2247d88c1a5aSDimitry Andric if (DefRange.IsSubfield) { 22483ca95b02SDimitry Andric // Unclear what matters here. 2249d88c1a5aSDimitry Andric DefRangeSubfieldRegisterSym Sym(S_DEFRANGE_SUBFIELD_REGISTER); 2250d88c1a5aSDimitry Andric Sym.Hdr.Register = DefRange.CVRegister; 2251d88c1a5aSDimitry Andric Sym.Hdr.MayHaveNoName = 0; 2252d88c1a5aSDimitry Andric Sym.Hdr.OffsetInParent = DefRange.StructOffset; 2253d88c1a5aSDimitry Andric 2254d88c1a5aSDimitry Andric ulittle16_t SymKind = ulittle16_t(S_DEFRANGE_SUBFIELD_REGISTER); 2255d88c1a5aSDimitry Andric BytePrefix += StringRef(reinterpret_cast<const char *>(&SymKind), 2256d88c1a5aSDimitry Andric sizeof(SymKind)); 2257d88c1a5aSDimitry Andric BytePrefix += StringRef(reinterpret_cast<const char *>(&Sym.Hdr), 2258d88c1a5aSDimitry Andric sizeof(Sym.Hdr)); 2259d88c1a5aSDimitry Andric } else { 2260d88c1a5aSDimitry Andric // Unclear what matters here. 2261d88c1a5aSDimitry Andric DefRangeRegisterSym Sym(S_DEFRANGE_REGISTER); 2262d88c1a5aSDimitry Andric Sym.Hdr.Register = DefRange.CVRegister; 2263d88c1a5aSDimitry Andric Sym.Hdr.MayHaveNoName = 0; 22643ca95b02SDimitry Andric ulittle16_t SymKind = ulittle16_t(S_DEFRANGE_REGISTER); 2265d88c1a5aSDimitry Andric BytePrefix += StringRef(reinterpret_cast<const char *>(&SymKind), 2266d88c1a5aSDimitry Andric sizeof(SymKind)); 2267d88c1a5aSDimitry Andric BytePrefix += StringRef(reinterpret_cast<const char *>(&Sym.Hdr), 2268d88c1a5aSDimitry Andric sizeof(Sym.Hdr)); 2269d88c1a5aSDimitry Andric } 22703ca95b02SDimitry Andric } 22713ca95b02SDimitry Andric OS.EmitCVDefRangeDirective(DefRange.Ranges, BytePrefix); 22723ca95b02SDimitry Andric } 22733ca95b02SDimitry Andric } 22743ca95b02SDimitry Andric 22757a7e6055SDimitry Andric void CodeViewDebug::endFunctionImpl(const MachineFunction *MF) { 22762cab237bSDimitry Andric const Function &GV = MF->getFunction(); 22772cab237bSDimitry Andric assert(FnDebugInfo.count(&GV)); 22782cab237bSDimitry Andric assert(CurFn == &FnDebugInfo[&GV]); 22793ca95b02SDimitry Andric 22802cab237bSDimitry Andric collectVariableInfo(GV.getSubprogram()); 22813ca95b02SDimitry Andric 22823ca95b02SDimitry Andric // Don't emit anything if we don't have any line tables. 22833ca95b02SDimitry Andric if (!CurFn->HaveLineInfo) { 22842cab237bSDimitry Andric FnDebugInfo.erase(&GV); 22853ca95b02SDimitry Andric CurFn = nullptr; 22863ca95b02SDimitry Andric return; 22873ca95b02SDimitry Andric } 22883ca95b02SDimitry Andric 22892cab237bSDimitry Andric CurFn->Annotations = MF->getCodeViewAnnotations(); 22902cab237bSDimitry Andric 22913ca95b02SDimitry Andric CurFn->End = Asm->getFunctionEnd(); 22923ca95b02SDimitry Andric 22933ca95b02SDimitry Andric CurFn = nullptr; 22943ca95b02SDimitry Andric } 22953ca95b02SDimitry Andric 22963ca95b02SDimitry Andric void CodeViewDebug::beginInstruction(const MachineInstr *MI) { 22973ca95b02SDimitry Andric DebugHandlerBase::beginInstruction(MI); 22983ca95b02SDimitry Andric 22993ca95b02SDimitry Andric // Ignore DBG_VALUE locations and function prologue. 23006c4bc1bdSDimitry Andric if (!Asm || !CurFn || MI->isDebugValue() || 23016c4bc1bdSDimitry Andric MI->getFlag(MachineInstr::FrameSetup)) 23023ca95b02SDimitry Andric return; 2303a580b014SDimitry Andric 2304a580b014SDimitry Andric // If the first instruction of a new MBB has no location, find the first 2305a580b014SDimitry Andric // instruction with a location and use that. 23063ca95b02SDimitry Andric DebugLoc DL = MI->getDebugLoc(); 2307a580b014SDimitry Andric if (!DL && MI->getParent() != PrevInstBB) { 2308a580b014SDimitry Andric for (const auto &NextMI : *MI->getParent()) { 23092cab237bSDimitry Andric if (NextMI.isDebugValue()) 23102cab237bSDimitry Andric continue; 2311a580b014SDimitry Andric DL = NextMI.getDebugLoc(); 2312a580b014SDimitry Andric if (DL) 2313a580b014SDimitry Andric break; 2314a580b014SDimitry Andric } 2315a580b014SDimitry Andric } 2316a580b014SDimitry Andric PrevInstBB = MI->getParent(); 2317a580b014SDimitry Andric 2318a580b014SDimitry Andric // If we still don't have a debug location, don't record a location. 2319a580b014SDimitry Andric if (!DL) 23203ca95b02SDimitry Andric return; 2321a580b014SDimitry Andric 23223ca95b02SDimitry Andric maybeRecordLocation(DL, Asm->MF); 23233ca95b02SDimitry Andric } 23243ca95b02SDimitry Andric 232589cb50c9SDimitry Andric MCSymbol *CodeViewDebug::beginCVSubsection(DebugSubsectionKind Kind) { 23263ca95b02SDimitry Andric MCSymbol *BeginLabel = MMI->getContext().createTempSymbol(), 23273ca95b02SDimitry Andric *EndLabel = MMI->getContext().createTempSymbol(); 23283ca95b02SDimitry Andric OS.EmitIntValue(unsigned(Kind), 4); 23293ca95b02SDimitry Andric OS.AddComment("Subsection size"); 23303ca95b02SDimitry Andric OS.emitAbsoluteSymbolDiff(EndLabel, BeginLabel, 4); 23313ca95b02SDimitry Andric OS.EmitLabel(BeginLabel); 23323ca95b02SDimitry Andric return EndLabel; 23333ca95b02SDimitry Andric } 23343ca95b02SDimitry Andric 23353ca95b02SDimitry Andric void CodeViewDebug::endCVSubsection(MCSymbol *EndLabel) { 23363ca95b02SDimitry Andric OS.EmitLabel(EndLabel); 23373ca95b02SDimitry Andric // Every subsection must be aligned to a 4-byte boundary. 23383ca95b02SDimitry Andric OS.EmitValueToAlignment(4); 23393ca95b02SDimitry Andric } 23403ca95b02SDimitry Andric 23413ca95b02SDimitry Andric void CodeViewDebug::emitDebugInfoForUDTs( 23422cab237bSDimitry Andric ArrayRef<std::pair<std::string, const DIType *>> UDTs) { 23432cab237bSDimitry Andric for (const auto &UDT : UDTs) { 23442cab237bSDimitry Andric const DIType *T = UDT.second; 23452cab237bSDimitry Andric assert(shouldEmitUdt(T)); 23462cab237bSDimitry Andric 23473ca95b02SDimitry Andric MCSymbol *UDTRecordBegin = MMI->getContext().createTempSymbol(), 23483ca95b02SDimitry Andric *UDTRecordEnd = MMI->getContext().createTempSymbol(); 23493ca95b02SDimitry Andric OS.AddComment("Record length"); 23503ca95b02SDimitry Andric OS.emitAbsoluteSymbolDiff(UDTRecordEnd, UDTRecordBegin, 2); 23513ca95b02SDimitry Andric OS.EmitLabel(UDTRecordBegin); 23523ca95b02SDimitry Andric 23533ca95b02SDimitry Andric OS.AddComment("Record kind: S_UDT"); 23543ca95b02SDimitry Andric OS.EmitIntValue(unsigned(SymbolKind::S_UDT), 2); 23553ca95b02SDimitry Andric 23563ca95b02SDimitry Andric OS.AddComment("Type"); 23572cab237bSDimitry Andric OS.EmitIntValue(getCompleteTypeIndex(T).getIndex(), 4); 23583ca95b02SDimitry Andric 23593ca95b02SDimitry Andric emitNullTerminatedSymbolName(OS, UDT.first); 23603ca95b02SDimitry Andric OS.EmitLabel(UDTRecordEnd); 23613ca95b02SDimitry Andric } 23623ca95b02SDimitry Andric } 23633ca95b02SDimitry Andric 23643ca95b02SDimitry Andric void CodeViewDebug::emitDebugInfoForGlobals() { 2365d88c1a5aSDimitry Andric DenseMap<const DIGlobalVariableExpression *, const GlobalVariable *> 2366d88c1a5aSDimitry Andric GlobalMap; 2367d88c1a5aSDimitry Andric for (const GlobalVariable &GV : MMI->getModule()->globals()) { 2368d88c1a5aSDimitry Andric SmallVector<DIGlobalVariableExpression *, 1> GVEs; 2369d88c1a5aSDimitry Andric GV.getDebugInfo(GVEs); 2370d88c1a5aSDimitry Andric for (const auto *GVE : GVEs) 2371d88c1a5aSDimitry Andric GlobalMap[GVE] = &GV; 2372d88c1a5aSDimitry Andric } 2373d88c1a5aSDimitry Andric 23743ca95b02SDimitry Andric NamedMDNode *CUs = MMI->getModule()->getNamedMetadata("llvm.dbg.cu"); 23753ca95b02SDimitry Andric for (const MDNode *Node : CUs->operands()) { 23763ca95b02SDimitry Andric const auto *CU = cast<DICompileUnit>(Node); 23773ca95b02SDimitry Andric 23783ca95b02SDimitry Andric // First, emit all globals that are not in a comdat in a single symbol 23793ca95b02SDimitry Andric // substream. MSVC doesn't like it if the substream is empty, so only open 23803ca95b02SDimitry Andric // it if we have at least one global to emit. 23813ca95b02SDimitry Andric switchToDebugSectionForSymbol(nullptr); 23823ca95b02SDimitry Andric MCSymbol *EndLabel = nullptr; 2383d88c1a5aSDimitry Andric for (const auto *GVE : CU->getGlobalVariables()) { 2384d88c1a5aSDimitry Andric if (const auto *GV = GlobalMap.lookup(GVE)) 23853ca95b02SDimitry Andric if (!GV->hasComdat() && !GV->isDeclarationForLinker()) { 23863ca95b02SDimitry Andric if (!EndLabel) { 23873ca95b02SDimitry Andric OS.AddComment("Symbol subsection for globals"); 238889cb50c9SDimitry Andric EndLabel = beginCVSubsection(DebugSubsectionKind::Symbols); 23893ca95b02SDimitry Andric } 2390d88c1a5aSDimitry Andric // FIXME: emitDebugInfoForGlobal() doesn't handle DIExpressions. 2391d88c1a5aSDimitry Andric emitDebugInfoForGlobal(GVE->getVariable(), GV, Asm->getSymbol(GV)); 23923ca95b02SDimitry Andric } 23933ca95b02SDimitry Andric } 23943ca95b02SDimitry Andric if (EndLabel) 23953ca95b02SDimitry Andric endCVSubsection(EndLabel); 23963ca95b02SDimitry Andric 23973ca95b02SDimitry Andric // Second, emit each global that is in a comdat into its own .debug$S 23983ca95b02SDimitry Andric // section along with its own symbol substream. 2399d88c1a5aSDimitry Andric for (const auto *GVE : CU->getGlobalVariables()) { 2400d88c1a5aSDimitry Andric if (const auto *GV = GlobalMap.lookup(GVE)) { 24013ca95b02SDimitry Andric if (GV->hasComdat()) { 24023ca95b02SDimitry Andric MCSymbol *GVSym = Asm->getSymbol(GV); 24033ca95b02SDimitry Andric OS.AddComment("Symbol subsection for " + 24045517e702SDimitry Andric Twine(GlobalValue::dropLLVMManglingEscape(GV->getName()))); 24053ca95b02SDimitry Andric switchToDebugSectionForSymbol(GVSym); 240689cb50c9SDimitry Andric EndLabel = beginCVSubsection(DebugSubsectionKind::Symbols); 2407d88c1a5aSDimitry Andric // FIXME: emitDebugInfoForGlobal() doesn't handle DIExpressions. 2408d88c1a5aSDimitry Andric emitDebugInfoForGlobal(GVE->getVariable(), GV, GVSym); 24093ca95b02SDimitry Andric endCVSubsection(EndLabel); 24103ca95b02SDimitry Andric } 24113ca95b02SDimitry Andric } 24123ca95b02SDimitry Andric } 24133ca95b02SDimitry Andric } 24143ca95b02SDimitry Andric } 24153ca95b02SDimitry Andric 24163ca95b02SDimitry Andric void CodeViewDebug::emitDebugInfoForRetainedTypes() { 24173ca95b02SDimitry Andric NamedMDNode *CUs = MMI->getModule()->getNamedMetadata("llvm.dbg.cu"); 24183ca95b02SDimitry Andric for (const MDNode *Node : CUs->operands()) { 24193ca95b02SDimitry Andric for (auto *Ty : cast<DICompileUnit>(Node)->getRetainedTypes()) { 24203ca95b02SDimitry Andric if (DIType *RT = dyn_cast<DIType>(Ty)) { 24213ca95b02SDimitry Andric getTypeIndex(RT); 24223ca95b02SDimitry Andric // FIXME: Add to global/local DTU list. 24233ca95b02SDimitry Andric } 24243ca95b02SDimitry Andric } 24253ca95b02SDimitry Andric } 24263ca95b02SDimitry Andric } 24273ca95b02SDimitry Andric 24283ca95b02SDimitry Andric void CodeViewDebug::emitDebugInfoForGlobal(const DIGlobalVariable *DIGV, 2429d88c1a5aSDimitry Andric const GlobalVariable *GV, 24303ca95b02SDimitry Andric MCSymbol *GVSym) { 24313ca95b02SDimitry Andric // DataSym record, see SymbolRecord.h for more info. 24323ca95b02SDimitry Andric // FIXME: Thread local data, etc 24333ca95b02SDimitry Andric MCSymbol *DataBegin = MMI->getContext().createTempSymbol(), 24343ca95b02SDimitry Andric *DataEnd = MMI->getContext().createTempSymbol(); 24353ca95b02SDimitry Andric OS.AddComment("Record length"); 24363ca95b02SDimitry Andric OS.emitAbsoluteSymbolDiff(DataEnd, DataBegin, 2); 24373ca95b02SDimitry Andric OS.EmitLabel(DataBegin); 24383ca95b02SDimitry Andric if (DIGV->isLocalToUnit()) { 24393ca95b02SDimitry Andric if (GV->isThreadLocal()) { 24403ca95b02SDimitry Andric OS.AddComment("Record kind: S_LTHREAD32"); 24413ca95b02SDimitry Andric OS.EmitIntValue(unsigned(SymbolKind::S_LTHREAD32), 2); 24423ca95b02SDimitry Andric } else { 24433ca95b02SDimitry Andric OS.AddComment("Record kind: S_LDATA32"); 24443ca95b02SDimitry Andric OS.EmitIntValue(unsigned(SymbolKind::S_LDATA32), 2); 24453ca95b02SDimitry Andric } 24463ca95b02SDimitry Andric } else { 24473ca95b02SDimitry Andric if (GV->isThreadLocal()) { 24483ca95b02SDimitry Andric OS.AddComment("Record kind: S_GTHREAD32"); 24493ca95b02SDimitry Andric OS.EmitIntValue(unsigned(SymbolKind::S_GTHREAD32), 2); 24503ca95b02SDimitry Andric } else { 24513ca95b02SDimitry Andric OS.AddComment("Record kind: S_GDATA32"); 24523ca95b02SDimitry Andric OS.EmitIntValue(unsigned(SymbolKind::S_GDATA32), 2); 24533ca95b02SDimitry Andric } 24543ca95b02SDimitry Andric } 24553ca95b02SDimitry Andric OS.AddComment("Type"); 24563ca95b02SDimitry Andric OS.EmitIntValue(getCompleteTypeIndex(DIGV->getType()).getIndex(), 4); 24573ca95b02SDimitry Andric OS.AddComment("DataOffset"); 2458d88c1a5aSDimitry Andric OS.EmitCOFFSecRel32(GVSym, /*Offset=*/0); 24593ca95b02SDimitry Andric OS.AddComment("Segment"); 24603ca95b02SDimitry Andric OS.EmitCOFFSectionIndex(GVSym); 24613ca95b02SDimitry Andric OS.AddComment("Name"); 24623ca95b02SDimitry Andric emitNullTerminatedSymbolName(OS, DIGV->getName()); 24633ca95b02SDimitry Andric OS.EmitLabel(DataEnd); 24643ca95b02SDimitry Andric } 2465