13ca95b02SDimitry Andric //===-- llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp --*- C++ -*--===// 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" 153ca95b02SDimitry Andric #include "llvm/ADT/TinyPtrVector.h" 163ca95b02SDimitry Andric #include "llvm/DebugInfo/CodeView/ByteStream.h" 173ca95b02SDimitry Andric #include "llvm/DebugInfo/CodeView/CVTypeVisitor.h" 183ca95b02SDimitry Andric #include "llvm/DebugInfo/CodeView/CodeView.h" 193ca95b02SDimitry Andric #include "llvm/DebugInfo/CodeView/FieldListRecordBuilder.h" 203ca95b02SDimitry Andric #include "llvm/DebugInfo/CodeView/Line.h" 213ca95b02SDimitry Andric #include "llvm/DebugInfo/CodeView/SymbolRecord.h" 223ca95b02SDimitry Andric #include "llvm/DebugInfo/CodeView/TypeDumper.h" 233ca95b02SDimitry Andric #include "llvm/DebugInfo/CodeView/TypeIndex.h" 243ca95b02SDimitry Andric #include "llvm/DebugInfo/CodeView/TypeRecord.h" 253ca95b02SDimitry Andric #include "llvm/DebugInfo/CodeView/TypeVisitorCallbacks.h" 263ca95b02SDimitry Andric #include "llvm/IR/Constants.h" 273ca95b02SDimitry Andric #include "llvm/MC/MCExpr.h" 283ca95b02SDimitry Andric #include "llvm/MC/MCSectionCOFF.h" 293ca95b02SDimitry Andric #include "llvm/MC/MCSymbol.h" 303ca95b02SDimitry Andric #include "llvm/Support/COFF.h" 313ca95b02SDimitry Andric #include "llvm/Support/ScopedPrinter.h" 323ca95b02SDimitry Andric #include "llvm/Target/TargetFrameLowering.h" 333ca95b02SDimitry Andric #include "llvm/Target/TargetRegisterInfo.h" 343ca95b02SDimitry Andric #include "llvm/Target/TargetSubtargetInfo.h" 353ca95b02SDimitry Andric 363ca95b02SDimitry Andric using namespace llvm; 373ca95b02SDimitry Andric using namespace llvm::codeview; 383ca95b02SDimitry Andric 393ca95b02SDimitry Andric CodeViewDebug::CodeViewDebug(AsmPrinter *AP) 403ca95b02SDimitry Andric : DebugHandlerBase(AP), OS(*Asm->OutStreamer), CurFn(nullptr) { 413ca95b02SDimitry Andric // If module doesn't have named metadata anchors or COFF debug section 423ca95b02SDimitry Andric // is not available, skip any debug info related stuff. 433ca95b02SDimitry Andric if (!MMI->getModule()->getNamedMetadata("llvm.dbg.cu") || 443ca95b02SDimitry Andric !AP->getObjFileLowering().getCOFFDebugSymbolsSection()) { 453ca95b02SDimitry Andric Asm = nullptr; 463ca95b02SDimitry Andric return; 473ca95b02SDimitry Andric } 483ca95b02SDimitry Andric 493ca95b02SDimitry Andric // Tell MMI that we have debug info. 503ca95b02SDimitry Andric MMI->setDebugInfoAvailability(true); 513ca95b02SDimitry Andric } 523ca95b02SDimitry Andric 533ca95b02SDimitry Andric StringRef CodeViewDebug::getFullFilepath(const DIFile *File) { 543ca95b02SDimitry Andric std::string &Filepath = FileToFilepathMap[File]; 553ca95b02SDimitry Andric if (!Filepath.empty()) 563ca95b02SDimitry Andric return Filepath; 573ca95b02SDimitry Andric 583ca95b02SDimitry Andric StringRef Dir = File->getDirectory(), Filename = File->getFilename(); 593ca95b02SDimitry Andric 603ca95b02SDimitry Andric // Clang emits directory and relative filename info into the IR, but CodeView 613ca95b02SDimitry Andric // operates on full paths. We could change Clang to emit full paths too, but 623ca95b02SDimitry Andric // that would increase the IR size and probably not needed for other users. 633ca95b02SDimitry Andric // For now, just concatenate and canonicalize the path here. 643ca95b02SDimitry Andric if (Filename.find(':') == 1) 653ca95b02SDimitry Andric Filepath = Filename; 663ca95b02SDimitry Andric else 673ca95b02SDimitry Andric Filepath = (Dir + "\\" + Filename).str(); 683ca95b02SDimitry Andric 693ca95b02SDimitry Andric // Canonicalize the path. We have to do it textually because we may no longer 703ca95b02SDimitry Andric // have access the file in the filesystem. 713ca95b02SDimitry Andric // First, replace all slashes with backslashes. 723ca95b02SDimitry Andric std::replace(Filepath.begin(), Filepath.end(), '/', '\\'); 733ca95b02SDimitry Andric 743ca95b02SDimitry Andric // Remove all "\.\" with "\". 753ca95b02SDimitry Andric size_t Cursor = 0; 763ca95b02SDimitry Andric while ((Cursor = Filepath.find("\\.\\", Cursor)) != std::string::npos) 773ca95b02SDimitry Andric Filepath.erase(Cursor, 2); 783ca95b02SDimitry Andric 793ca95b02SDimitry Andric // Replace all "\XXX\..\" with "\". Don't try too hard though as the original 803ca95b02SDimitry Andric // path should be well-formatted, e.g. start with a drive letter, etc. 813ca95b02SDimitry Andric Cursor = 0; 823ca95b02SDimitry Andric while ((Cursor = Filepath.find("\\..\\", Cursor)) != std::string::npos) { 833ca95b02SDimitry Andric // Something's wrong if the path starts with "\..\", abort. 843ca95b02SDimitry Andric if (Cursor == 0) 853ca95b02SDimitry Andric break; 863ca95b02SDimitry Andric 873ca95b02SDimitry Andric size_t PrevSlash = Filepath.rfind('\\', Cursor - 1); 883ca95b02SDimitry Andric if (PrevSlash == std::string::npos) 893ca95b02SDimitry Andric // Something's wrong, abort. 903ca95b02SDimitry Andric break; 913ca95b02SDimitry Andric 923ca95b02SDimitry Andric Filepath.erase(PrevSlash, Cursor + 3 - PrevSlash); 933ca95b02SDimitry Andric // The next ".." might be following the one we've just erased. 943ca95b02SDimitry Andric Cursor = PrevSlash; 953ca95b02SDimitry Andric } 963ca95b02SDimitry Andric 973ca95b02SDimitry Andric // Remove all duplicate backslashes. 983ca95b02SDimitry Andric Cursor = 0; 993ca95b02SDimitry Andric while ((Cursor = Filepath.find("\\\\", Cursor)) != std::string::npos) 1003ca95b02SDimitry Andric Filepath.erase(Cursor, 1); 1013ca95b02SDimitry Andric 1023ca95b02SDimitry Andric return Filepath; 1033ca95b02SDimitry Andric } 1043ca95b02SDimitry Andric 1053ca95b02SDimitry Andric unsigned CodeViewDebug::maybeRecordFile(const DIFile *F) { 1063ca95b02SDimitry Andric unsigned NextId = FileIdMap.size() + 1; 1073ca95b02SDimitry Andric auto Insertion = FileIdMap.insert(std::make_pair(F, NextId)); 1083ca95b02SDimitry Andric if (Insertion.second) { 1093ca95b02SDimitry Andric // We have to compute the full filepath and emit a .cv_file directive. 1103ca95b02SDimitry Andric StringRef FullPath = getFullFilepath(F); 1113ca95b02SDimitry Andric NextId = OS.EmitCVFileDirective(NextId, FullPath); 1123ca95b02SDimitry Andric assert(NextId == FileIdMap.size() && ".cv_file directive failed"); 1133ca95b02SDimitry Andric } 1143ca95b02SDimitry Andric return Insertion.first->second; 1153ca95b02SDimitry Andric } 1163ca95b02SDimitry Andric 1173ca95b02SDimitry Andric CodeViewDebug::InlineSite & 1183ca95b02SDimitry Andric CodeViewDebug::getInlineSite(const DILocation *InlinedAt, 1193ca95b02SDimitry Andric const DISubprogram *Inlinee) { 1203ca95b02SDimitry Andric auto SiteInsertion = CurFn->InlineSites.insert({InlinedAt, InlineSite()}); 1213ca95b02SDimitry Andric InlineSite *Site = &SiteInsertion.first->second; 1223ca95b02SDimitry Andric if (SiteInsertion.second) { 1233ca95b02SDimitry Andric Site->SiteFuncId = NextFuncId++; 1243ca95b02SDimitry Andric Site->Inlinee = Inlinee; 1253ca95b02SDimitry Andric InlinedSubprograms.insert(Inlinee); 1263ca95b02SDimitry Andric getFuncIdForSubprogram(Inlinee); 1273ca95b02SDimitry Andric } 1283ca95b02SDimitry Andric return *Site; 1293ca95b02SDimitry Andric } 1303ca95b02SDimitry Andric 1313ca95b02SDimitry Andric static StringRef getPrettyScopeName(const DIScope *Scope) { 1323ca95b02SDimitry Andric StringRef ScopeName = Scope->getName(); 1333ca95b02SDimitry Andric if (!ScopeName.empty()) 1343ca95b02SDimitry Andric return ScopeName; 1353ca95b02SDimitry Andric 1363ca95b02SDimitry Andric switch (Scope->getTag()) { 1373ca95b02SDimitry Andric case dwarf::DW_TAG_enumeration_type: 1383ca95b02SDimitry Andric case dwarf::DW_TAG_class_type: 1393ca95b02SDimitry Andric case dwarf::DW_TAG_structure_type: 1403ca95b02SDimitry Andric case dwarf::DW_TAG_union_type: 1413ca95b02SDimitry Andric return "<unnamed-tag>"; 1423ca95b02SDimitry Andric case dwarf::DW_TAG_namespace: 1433ca95b02SDimitry Andric return "`anonymous namespace'"; 1443ca95b02SDimitry Andric } 1453ca95b02SDimitry Andric 1463ca95b02SDimitry Andric return StringRef(); 1473ca95b02SDimitry Andric } 1483ca95b02SDimitry Andric 1493ca95b02SDimitry Andric static const DISubprogram *getQualifiedNameComponents( 1503ca95b02SDimitry Andric const DIScope *Scope, SmallVectorImpl<StringRef> &QualifiedNameComponents) { 1513ca95b02SDimitry Andric const DISubprogram *ClosestSubprogram = nullptr; 1523ca95b02SDimitry Andric while (Scope != nullptr) { 1533ca95b02SDimitry Andric if (ClosestSubprogram == nullptr) 1543ca95b02SDimitry Andric ClosestSubprogram = dyn_cast<DISubprogram>(Scope); 1553ca95b02SDimitry Andric StringRef ScopeName = getPrettyScopeName(Scope); 1563ca95b02SDimitry Andric if (!ScopeName.empty()) 1573ca95b02SDimitry Andric QualifiedNameComponents.push_back(ScopeName); 1583ca95b02SDimitry Andric Scope = Scope->getScope().resolve(); 1593ca95b02SDimitry Andric } 1603ca95b02SDimitry Andric return ClosestSubprogram; 1613ca95b02SDimitry Andric } 1623ca95b02SDimitry Andric 1633ca95b02SDimitry Andric static std::string getQualifiedName(ArrayRef<StringRef> QualifiedNameComponents, 1643ca95b02SDimitry Andric StringRef TypeName) { 1653ca95b02SDimitry Andric std::string FullyQualifiedName; 1663ca95b02SDimitry Andric for (StringRef QualifiedNameComponent : reverse(QualifiedNameComponents)) { 1673ca95b02SDimitry Andric FullyQualifiedName.append(QualifiedNameComponent); 1683ca95b02SDimitry Andric FullyQualifiedName.append("::"); 1693ca95b02SDimitry Andric } 1703ca95b02SDimitry Andric FullyQualifiedName.append(TypeName); 1713ca95b02SDimitry Andric return FullyQualifiedName; 1723ca95b02SDimitry Andric } 1733ca95b02SDimitry Andric 1743ca95b02SDimitry Andric static std::string getFullyQualifiedName(const DIScope *Scope, StringRef Name) { 1753ca95b02SDimitry Andric SmallVector<StringRef, 5> QualifiedNameComponents; 1763ca95b02SDimitry Andric getQualifiedNameComponents(Scope, QualifiedNameComponents); 1773ca95b02SDimitry Andric return getQualifiedName(QualifiedNameComponents, Name); 1783ca95b02SDimitry Andric } 1793ca95b02SDimitry Andric 1803ca95b02SDimitry Andric struct CodeViewDebug::TypeLoweringScope { 1813ca95b02SDimitry Andric TypeLoweringScope(CodeViewDebug &CVD) : CVD(CVD) { ++CVD.TypeEmissionLevel; } 1823ca95b02SDimitry Andric ~TypeLoweringScope() { 1833ca95b02SDimitry Andric // Don't decrement TypeEmissionLevel until after emitting deferred types, so 1843ca95b02SDimitry Andric // inner TypeLoweringScopes don't attempt to emit deferred types. 1853ca95b02SDimitry Andric if (CVD.TypeEmissionLevel == 1) 1863ca95b02SDimitry Andric CVD.emitDeferredCompleteTypes(); 1873ca95b02SDimitry Andric --CVD.TypeEmissionLevel; 1883ca95b02SDimitry Andric } 1893ca95b02SDimitry Andric CodeViewDebug &CVD; 1903ca95b02SDimitry Andric }; 1913ca95b02SDimitry Andric 1923ca95b02SDimitry Andric static std::string getFullyQualifiedName(const DIScope *Ty) { 1933ca95b02SDimitry Andric const DIScope *Scope = Ty->getScope().resolve(); 1943ca95b02SDimitry Andric return getFullyQualifiedName(Scope, getPrettyScopeName(Ty)); 1953ca95b02SDimitry Andric } 1963ca95b02SDimitry Andric 1973ca95b02SDimitry Andric TypeIndex CodeViewDebug::getScopeIndex(const DIScope *Scope) { 1983ca95b02SDimitry Andric // No scope means global scope and that uses the zero index. 1993ca95b02SDimitry Andric if (!Scope || isa<DIFile>(Scope)) 2003ca95b02SDimitry Andric return TypeIndex(); 2013ca95b02SDimitry Andric 2023ca95b02SDimitry Andric assert(!isa<DIType>(Scope) && "shouldn't make a namespace scope for a type"); 2033ca95b02SDimitry Andric 2043ca95b02SDimitry Andric // Check if we've already translated this scope. 2053ca95b02SDimitry Andric auto I = TypeIndices.find({Scope, nullptr}); 2063ca95b02SDimitry Andric if (I != TypeIndices.end()) 2073ca95b02SDimitry Andric return I->second; 2083ca95b02SDimitry Andric 2093ca95b02SDimitry Andric // Build the fully qualified name of the scope. 2103ca95b02SDimitry Andric std::string ScopeName = getFullyQualifiedName(Scope); 2113ca95b02SDimitry Andric TypeIndex TI = 2123ca95b02SDimitry Andric TypeTable.writeStringId(StringIdRecord(TypeIndex(), ScopeName)); 2133ca95b02SDimitry Andric return recordTypeIndexForDINode(Scope, TI); 2143ca95b02SDimitry Andric } 2153ca95b02SDimitry Andric 2163ca95b02SDimitry Andric TypeIndex CodeViewDebug::getFuncIdForSubprogram(const DISubprogram *SP) { 2173ca95b02SDimitry Andric // It's possible to ask for the FuncId of a function which doesn't have a 2183ca95b02SDimitry Andric // subprogram: inlining a function with debug info into a function with none. 2193ca95b02SDimitry Andric if (!SP) 2203ca95b02SDimitry Andric return TypeIndex::None(); 2213ca95b02SDimitry Andric 2223ca95b02SDimitry Andric // Check if we've already translated this subprogram. 2233ca95b02SDimitry Andric auto I = TypeIndices.find({SP, nullptr}); 2243ca95b02SDimitry Andric if (I != TypeIndices.end()) 2253ca95b02SDimitry Andric return I->second; 2263ca95b02SDimitry Andric 2273ca95b02SDimitry Andric // The display name includes function template arguments. Drop them to match 2283ca95b02SDimitry Andric // MSVC. 2293ca95b02SDimitry Andric StringRef DisplayName = SP->getDisplayName().split('<').first; 2303ca95b02SDimitry Andric 2313ca95b02SDimitry Andric const DIScope *Scope = SP->getScope().resolve(); 2323ca95b02SDimitry Andric TypeIndex TI; 2333ca95b02SDimitry Andric if (const auto *Class = dyn_cast_or_null<DICompositeType>(Scope)) { 2343ca95b02SDimitry Andric // If the scope is a DICompositeType, then this must be a method. Member 2353ca95b02SDimitry Andric // function types take some special handling, and require access to the 2363ca95b02SDimitry Andric // subprogram. 2373ca95b02SDimitry Andric TypeIndex ClassType = getTypeIndex(Class); 2383ca95b02SDimitry Andric MemberFuncIdRecord MFuncId(ClassType, getMemberFunctionType(SP, Class), 2393ca95b02SDimitry Andric DisplayName); 2403ca95b02SDimitry Andric TI = TypeTable.writeMemberFuncId(MFuncId); 2413ca95b02SDimitry Andric } else { 2423ca95b02SDimitry Andric // Otherwise, this must be a free function. 2433ca95b02SDimitry Andric TypeIndex ParentScope = getScopeIndex(Scope); 2443ca95b02SDimitry Andric FuncIdRecord FuncId(ParentScope, getTypeIndex(SP->getType()), DisplayName); 2453ca95b02SDimitry Andric TI = TypeTable.writeFuncId(FuncId); 2463ca95b02SDimitry Andric } 2473ca95b02SDimitry Andric 2483ca95b02SDimitry Andric return recordTypeIndexForDINode(SP, TI); 2493ca95b02SDimitry Andric } 2503ca95b02SDimitry Andric 2513ca95b02SDimitry Andric TypeIndex CodeViewDebug::getMemberFunctionType(const DISubprogram *SP, 2523ca95b02SDimitry Andric const DICompositeType *Class) { 2533ca95b02SDimitry Andric // Always use the method declaration as the key for the function type. The 2543ca95b02SDimitry Andric // method declaration contains the this adjustment. 2553ca95b02SDimitry Andric if (SP->getDeclaration()) 2563ca95b02SDimitry Andric SP = SP->getDeclaration(); 2573ca95b02SDimitry Andric assert(!SP->getDeclaration() && "should use declaration as key"); 2583ca95b02SDimitry Andric 2593ca95b02SDimitry Andric // Key the MemberFunctionRecord into the map as {SP, Class}. It won't collide 2603ca95b02SDimitry Andric // with the MemberFuncIdRecord, which is keyed in as {SP, nullptr}. 2613ca95b02SDimitry Andric auto I = TypeIndices.find({SP, Class}); 2623ca95b02SDimitry Andric if (I != TypeIndices.end()) 2633ca95b02SDimitry Andric return I->second; 2643ca95b02SDimitry Andric 2653ca95b02SDimitry Andric // Make sure complete type info for the class is emitted *after* the member 2663ca95b02SDimitry Andric // function type, as the complete class type is likely to reference this 2673ca95b02SDimitry Andric // member function type. 2683ca95b02SDimitry Andric TypeLoweringScope S(*this); 2693ca95b02SDimitry Andric TypeIndex TI = 2703ca95b02SDimitry Andric lowerTypeMemberFunction(SP->getType(), Class, SP->getThisAdjustment()); 2713ca95b02SDimitry Andric return recordTypeIndexForDINode(SP, TI, Class); 2723ca95b02SDimitry Andric } 2733ca95b02SDimitry Andric 2743ca95b02SDimitry Andric TypeIndex CodeViewDebug::recordTypeIndexForDINode(const DINode *Node, 2753ca95b02SDimitry Andric TypeIndex TI, 2763ca95b02SDimitry Andric const DIType *ClassTy) { 2773ca95b02SDimitry Andric auto InsertResult = TypeIndices.insert({{Node, ClassTy}, TI}); 2783ca95b02SDimitry Andric (void)InsertResult; 2793ca95b02SDimitry Andric assert(InsertResult.second && "DINode was already assigned a type index"); 2803ca95b02SDimitry Andric return TI; 2813ca95b02SDimitry Andric } 2823ca95b02SDimitry Andric 2833ca95b02SDimitry Andric unsigned CodeViewDebug::getPointerSizeInBytes() { 2843ca95b02SDimitry Andric return MMI->getModule()->getDataLayout().getPointerSizeInBits() / 8; 2853ca95b02SDimitry Andric } 2863ca95b02SDimitry Andric 2873ca95b02SDimitry Andric void CodeViewDebug::recordLocalVariable(LocalVariable &&Var, 2883ca95b02SDimitry Andric const DILocation *InlinedAt) { 2893ca95b02SDimitry Andric if (InlinedAt) { 2903ca95b02SDimitry Andric // This variable was inlined. Associate it with the InlineSite. 2913ca95b02SDimitry Andric const DISubprogram *Inlinee = Var.DIVar->getScope()->getSubprogram(); 2923ca95b02SDimitry Andric InlineSite &Site = getInlineSite(InlinedAt, Inlinee); 2933ca95b02SDimitry Andric Site.InlinedLocals.emplace_back(Var); 2943ca95b02SDimitry Andric } else { 2953ca95b02SDimitry Andric // This variable goes in the main ProcSym. 2963ca95b02SDimitry Andric CurFn->Locals.emplace_back(Var); 2973ca95b02SDimitry Andric } 2983ca95b02SDimitry Andric } 2993ca95b02SDimitry Andric 3003ca95b02SDimitry Andric static void addLocIfNotPresent(SmallVectorImpl<const DILocation *> &Locs, 3013ca95b02SDimitry Andric const DILocation *Loc) { 3023ca95b02SDimitry Andric auto B = Locs.begin(), E = Locs.end(); 3033ca95b02SDimitry Andric if (std::find(B, E, Loc) == E) 3043ca95b02SDimitry Andric Locs.push_back(Loc); 3053ca95b02SDimitry Andric } 3063ca95b02SDimitry Andric 3073ca95b02SDimitry Andric void CodeViewDebug::maybeRecordLocation(const DebugLoc &DL, 3083ca95b02SDimitry Andric const MachineFunction *MF) { 3093ca95b02SDimitry Andric // Skip this instruction if it has the same location as the previous one. 3103ca95b02SDimitry Andric if (DL == CurFn->LastLoc) 3113ca95b02SDimitry Andric return; 3123ca95b02SDimitry Andric 3133ca95b02SDimitry Andric const DIScope *Scope = DL.get()->getScope(); 3143ca95b02SDimitry Andric if (!Scope) 3153ca95b02SDimitry Andric return; 3163ca95b02SDimitry Andric 3173ca95b02SDimitry Andric // Skip this line if it is longer than the maximum we can record. 3183ca95b02SDimitry Andric LineInfo LI(DL.getLine(), DL.getLine(), /*IsStatement=*/true); 3193ca95b02SDimitry Andric if (LI.getStartLine() != DL.getLine() || LI.isAlwaysStepInto() || 3203ca95b02SDimitry Andric LI.isNeverStepInto()) 3213ca95b02SDimitry Andric return; 3223ca95b02SDimitry Andric 3233ca95b02SDimitry Andric ColumnInfo CI(DL.getCol(), /*EndColumn=*/0); 3243ca95b02SDimitry Andric if (CI.getStartColumn() != DL.getCol()) 3253ca95b02SDimitry Andric return; 3263ca95b02SDimitry Andric 3273ca95b02SDimitry Andric if (!CurFn->HaveLineInfo) 3283ca95b02SDimitry Andric CurFn->HaveLineInfo = true; 3293ca95b02SDimitry Andric unsigned FileId = 0; 3303ca95b02SDimitry Andric if (CurFn->LastLoc.get() && CurFn->LastLoc->getFile() == DL->getFile()) 3313ca95b02SDimitry Andric FileId = CurFn->LastFileId; 3323ca95b02SDimitry Andric else 3333ca95b02SDimitry Andric FileId = CurFn->LastFileId = maybeRecordFile(DL->getFile()); 3343ca95b02SDimitry Andric CurFn->LastLoc = DL; 3353ca95b02SDimitry Andric 3363ca95b02SDimitry Andric unsigned FuncId = CurFn->FuncId; 3373ca95b02SDimitry Andric if (const DILocation *SiteLoc = DL->getInlinedAt()) { 3383ca95b02SDimitry Andric const DILocation *Loc = DL.get(); 3393ca95b02SDimitry Andric 3403ca95b02SDimitry Andric // If this location was actually inlined from somewhere else, give it the ID 3413ca95b02SDimitry Andric // of the inline call site. 3423ca95b02SDimitry Andric FuncId = 3433ca95b02SDimitry Andric getInlineSite(SiteLoc, Loc->getScope()->getSubprogram()).SiteFuncId; 3443ca95b02SDimitry Andric 3453ca95b02SDimitry Andric // Ensure we have links in the tree of inline call sites. 3463ca95b02SDimitry Andric bool FirstLoc = true; 3473ca95b02SDimitry Andric while ((SiteLoc = Loc->getInlinedAt())) { 3483ca95b02SDimitry Andric InlineSite &Site = 3493ca95b02SDimitry Andric getInlineSite(SiteLoc, Loc->getScope()->getSubprogram()); 3503ca95b02SDimitry Andric if (!FirstLoc) 3513ca95b02SDimitry Andric addLocIfNotPresent(Site.ChildSites, Loc); 3523ca95b02SDimitry Andric FirstLoc = false; 3533ca95b02SDimitry Andric Loc = SiteLoc; 3543ca95b02SDimitry Andric } 3553ca95b02SDimitry Andric addLocIfNotPresent(CurFn->ChildSites, Loc); 3563ca95b02SDimitry Andric } 3573ca95b02SDimitry Andric 3583ca95b02SDimitry Andric OS.EmitCVLocDirective(FuncId, FileId, DL.getLine(), DL.getCol(), 3593ca95b02SDimitry Andric /*PrologueEnd=*/false, 3603ca95b02SDimitry Andric /*IsStmt=*/false, DL->getFilename()); 3613ca95b02SDimitry Andric } 3623ca95b02SDimitry Andric 3633ca95b02SDimitry Andric void CodeViewDebug::emitCodeViewMagicVersion() { 3643ca95b02SDimitry Andric OS.EmitValueToAlignment(4); 3653ca95b02SDimitry Andric OS.AddComment("Debug section magic"); 3663ca95b02SDimitry Andric OS.EmitIntValue(COFF::DEBUG_SECTION_MAGIC, 4); 3673ca95b02SDimitry Andric } 3683ca95b02SDimitry Andric 3693ca95b02SDimitry Andric void CodeViewDebug::endModule() { 3703ca95b02SDimitry Andric if (!Asm || !MMI->hasDebugInfo()) 3713ca95b02SDimitry Andric return; 3723ca95b02SDimitry Andric 3733ca95b02SDimitry Andric assert(Asm != nullptr); 3743ca95b02SDimitry Andric 3753ca95b02SDimitry Andric // The COFF .debug$S section consists of several subsections, each starting 3763ca95b02SDimitry Andric // with a 4-byte control code (e.g. 0xF1, 0xF2, etc) and then a 4-byte length 3773ca95b02SDimitry Andric // of the payload followed by the payload itself. The subsections are 4-byte 3783ca95b02SDimitry Andric // aligned. 3793ca95b02SDimitry Andric 3803ca95b02SDimitry Andric // Use the generic .debug$S section, and make a subsection for all the inlined 3813ca95b02SDimitry Andric // subprograms. 3823ca95b02SDimitry Andric switchToDebugSectionForSymbol(nullptr); 3833ca95b02SDimitry Andric emitInlineeLinesSubsection(); 3843ca95b02SDimitry Andric 3853ca95b02SDimitry Andric // Emit per-function debug information. 3863ca95b02SDimitry Andric for (auto &P : FnDebugInfo) 3873ca95b02SDimitry Andric if (!P.first->isDeclarationForLinker()) 3883ca95b02SDimitry Andric emitDebugInfoForFunction(P.first, P.second); 3893ca95b02SDimitry Andric 3903ca95b02SDimitry Andric // Emit global variable debug information. 3913ca95b02SDimitry Andric setCurrentSubprogram(nullptr); 3923ca95b02SDimitry Andric emitDebugInfoForGlobals(); 3933ca95b02SDimitry Andric 3943ca95b02SDimitry Andric // Emit retained types. 3953ca95b02SDimitry Andric emitDebugInfoForRetainedTypes(); 3963ca95b02SDimitry Andric 3973ca95b02SDimitry Andric // Switch back to the generic .debug$S section after potentially processing 3983ca95b02SDimitry Andric // comdat symbol sections. 3993ca95b02SDimitry Andric switchToDebugSectionForSymbol(nullptr); 4003ca95b02SDimitry Andric 4013ca95b02SDimitry Andric // Emit UDT records for any types used by global variables. 4023ca95b02SDimitry Andric if (!GlobalUDTs.empty()) { 4033ca95b02SDimitry Andric MCSymbol *SymbolsEnd = beginCVSubsection(ModuleSubstreamKind::Symbols); 4043ca95b02SDimitry Andric emitDebugInfoForUDTs(GlobalUDTs); 4053ca95b02SDimitry Andric endCVSubsection(SymbolsEnd); 4063ca95b02SDimitry Andric } 4073ca95b02SDimitry Andric 4083ca95b02SDimitry Andric // This subsection holds a file index to offset in string table table. 4093ca95b02SDimitry Andric OS.AddComment("File index to string table offset subsection"); 4103ca95b02SDimitry Andric OS.EmitCVFileChecksumsDirective(); 4113ca95b02SDimitry Andric 4123ca95b02SDimitry Andric // This subsection holds the string table. 4133ca95b02SDimitry Andric OS.AddComment("String table"); 4143ca95b02SDimitry Andric OS.EmitCVStringTableDirective(); 4153ca95b02SDimitry Andric 4163ca95b02SDimitry Andric // Emit type information last, so that any types we translate while emitting 4173ca95b02SDimitry Andric // function info are included. 4183ca95b02SDimitry Andric emitTypeInformation(); 4193ca95b02SDimitry Andric 4203ca95b02SDimitry Andric clear(); 4213ca95b02SDimitry Andric } 4223ca95b02SDimitry Andric 4233ca95b02SDimitry Andric static void emitNullTerminatedSymbolName(MCStreamer &OS, StringRef S) { 4243ca95b02SDimitry Andric // Microsoft's linker seems to have trouble with symbol names longer than 4253ca95b02SDimitry Andric // 0xffd8 bytes. 4263ca95b02SDimitry Andric S = S.substr(0, 0xffd8); 4273ca95b02SDimitry Andric SmallString<32> NullTerminatedString(S); 4283ca95b02SDimitry Andric NullTerminatedString.push_back('\0'); 4293ca95b02SDimitry Andric OS.EmitBytes(NullTerminatedString); 4303ca95b02SDimitry Andric } 4313ca95b02SDimitry Andric 4323ca95b02SDimitry Andric void CodeViewDebug::emitTypeInformation() { 4333ca95b02SDimitry Andric // Do nothing if we have no debug info or if no non-trivial types were emitted 4343ca95b02SDimitry Andric // to TypeTable during codegen. 4353ca95b02SDimitry Andric NamedMDNode *CU_Nodes = MMI->getModule()->getNamedMetadata("llvm.dbg.cu"); 4363ca95b02SDimitry Andric if (!CU_Nodes) 4373ca95b02SDimitry Andric return; 4383ca95b02SDimitry Andric if (TypeTable.empty()) 4393ca95b02SDimitry Andric return; 4403ca95b02SDimitry Andric 4413ca95b02SDimitry Andric // Start the .debug$T section with 0x4. 4423ca95b02SDimitry Andric OS.SwitchSection(Asm->getObjFileLowering().getCOFFDebugTypesSection()); 4433ca95b02SDimitry Andric emitCodeViewMagicVersion(); 4443ca95b02SDimitry Andric 4453ca95b02SDimitry Andric SmallString<8> CommentPrefix; 4463ca95b02SDimitry Andric if (OS.isVerboseAsm()) { 4473ca95b02SDimitry Andric CommentPrefix += '\t'; 4483ca95b02SDimitry Andric CommentPrefix += Asm->MAI->getCommentString(); 4493ca95b02SDimitry Andric CommentPrefix += ' '; 4503ca95b02SDimitry Andric } 4513ca95b02SDimitry Andric 4523ca95b02SDimitry Andric CVTypeDumper CVTD(nullptr, /*PrintRecordBytes=*/false); 4533ca95b02SDimitry Andric TypeTable.ForEachRecord( 4543ca95b02SDimitry Andric [&](TypeIndex Index, StringRef Record) { 4553ca95b02SDimitry Andric if (OS.isVerboseAsm()) { 4563ca95b02SDimitry Andric // Emit a block comment describing the type record for readability. 4573ca95b02SDimitry Andric SmallString<512> CommentBlock; 4583ca95b02SDimitry Andric raw_svector_ostream CommentOS(CommentBlock); 4593ca95b02SDimitry Andric ScopedPrinter SP(CommentOS); 4603ca95b02SDimitry Andric SP.setPrefix(CommentPrefix); 4613ca95b02SDimitry Andric CVTD.setPrinter(&SP); 4623ca95b02SDimitry Andric Error E = CVTD.dump({Record.bytes_begin(), Record.bytes_end()}); 4633ca95b02SDimitry Andric if (E) { 4643ca95b02SDimitry Andric logAllUnhandledErrors(std::move(E), errs(), "error: "); 4653ca95b02SDimitry Andric llvm_unreachable("produced malformed type record"); 4663ca95b02SDimitry Andric } 4673ca95b02SDimitry Andric // emitRawComment will insert its own tab and comment string before 4683ca95b02SDimitry Andric // the first line, so strip off our first one. It also prints its own 4693ca95b02SDimitry Andric // newline. 4703ca95b02SDimitry Andric OS.emitRawComment( 4713ca95b02SDimitry Andric CommentOS.str().drop_front(CommentPrefix.size() - 1).rtrim()); 4723ca95b02SDimitry Andric } else { 4733ca95b02SDimitry Andric #ifndef NDEBUG 4743ca95b02SDimitry Andric // Assert that the type data is valid even if we aren't dumping 4753ca95b02SDimitry Andric // comments. The MSVC linker doesn't do much type record validation, 4763ca95b02SDimitry Andric // so the first link of an invalid type record can succeed while 4773ca95b02SDimitry Andric // subsequent links will fail with LNK1285. 4783ca95b02SDimitry Andric ByteStream<> Stream({Record.bytes_begin(), Record.bytes_end()}); 4793ca95b02SDimitry Andric CVTypeArray Types; 4803ca95b02SDimitry Andric StreamReader Reader(Stream); 4813ca95b02SDimitry Andric Error E = Reader.readArray(Types, Reader.getLength()); 4823ca95b02SDimitry Andric if (!E) { 4833ca95b02SDimitry Andric TypeVisitorCallbacks C; 4843ca95b02SDimitry Andric E = CVTypeVisitor(C).visitTypeStream(Types); 4853ca95b02SDimitry Andric } 4863ca95b02SDimitry Andric if (E) { 4873ca95b02SDimitry Andric logAllUnhandledErrors(std::move(E), errs(), "error: "); 4883ca95b02SDimitry Andric llvm_unreachable("produced malformed type record"); 4893ca95b02SDimitry Andric } 4903ca95b02SDimitry Andric #endif 4913ca95b02SDimitry Andric } 4923ca95b02SDimitry Andric OS.EmitBinaryData(Record); 4933ca95b02SDimitry Andric }); 4943ca95b02SDimitry Andric } 4953ca95b02SDimitry Andric 4963ca95b02SDimitry Andric void CodeViewDebug::emitInlineeLinesSubsection() { 4973ca95b02SDimitry Andric if (InlinedSubprograms.empty()) 4983ca95b02SDimitry Andric return; 4993ca95b02SDimitry Andric 5003ca95b02SDimitry Andric OS.AddComment("Inlinee lines subsection"); 5013ca95b02SDimitry Andric MCSymbol *InlineEnd = beginCVSubsection(ModuleSubstreamKind::InlineeLines); 5023ca95b02SDimitry Andric 5033ca95b02SDimitry Andric // We don't provide any extra file info. 5043ca95b02SDimitry Andric // FIXME: Find out if debuggers use this info. 5053ca95b02SDimitry Andric OS.AddComment("Inlinee lines signature"); 5063ca95b02SDimitry Andric OS.EmitIntValue(unsigned(InlineeLinesSignature::Normal), 4); 5073ca95b02SDimitry Andric 5083ca95b02SDimitry Andric for (const DISubprogram *SP : InlinedSubprograms) { 5093ca95b02SDimitry Andric assert(TypeIndices.count({SP, nullptr})); 5103ca95b02SDimitry Andric TypeIndex InlineeIdx = TypeIndices[{SP, nullptr}]; 5113ca95b02SDimitry Andric 5123ca95b02SDimitry Andric OS.AddBlankLine(); 5133ca95b02SDimitry Andric unsigned FileId = maybeRecordFile(SP->getFile()); 5143ca95b02SDimitry Andric OS.AddComment("Inlined function " + SP->getDisplayName() + " starts at " + 5153ca95b02SDimitry Andric SP->getFilename() + Twine(':') + Twine(SP->getLine())); 5163ca95b02SDimitry Andric OS.AddBlankLine(); 5173ca95b02SDimitry Andric // The filechecksum table uses 8 byte entries for now, and file ids start at 5183ca95b02SDimitry Andric // 1. 5193ca95b02SDimitry Andric unsigned FileOffset = (FileId - 1) * 8; 5203ca95b02SDimitry Andric OS.AddComment("Type index of inlined function"); 5213ca95b02SDimitry Andric OS.EmitIntValue(InlineeIdx.getIndex(), 4); 5223ca95b02SDimitry Andric OS.AddComment("Offset into filechecksum table"); 5233ca95b02SDimitry Andric OS.EmitIntValue(FileOffset, 4); 5243ca95b02SDimitry Andric OS.AddComment("Starting line number"); 5253ca95b02SDimitry Andric OS.EmitIntValue(SP->getLine(), 4); 5263ca95b02SDimitry Andric } 5273ca95b02SDimitry Andric 5283ca95b02SDimitry Andric endCVSubsection(InlineEnd); 5293ca95b02SDimitry Andric } 5303ca95b02SDimitry Andric 5313ca95b02SDimitry Andric void CodeViewDebug::collectInlineSiteChildren( 5323ca95b02SDimitry Andric SmallVectorImpl<unsigned> &Children, const FunctionInfo &FI, 5333ca95b02SDimitry Andric const InlineSite &Site) { 5343ca95b02SDimitry Andric for (const DILocation *ChildSiteLoc : Site.ChildSites) { 5353ca95b02SDimitry Andric auto I = FI.InlineSites.find(ChildSiteLoc); 5363ca95b02SDimitry Andric const InlineSite &ChildSite = I->second; 5373ca95b02SDimitry Andric Children.push_back(ChildSite.SiteFuncId); 5383ca95b02SDimitry Andric collectInlineSiteChildren(Children, FI, ChildSite); 5393ca95b02SDimitry Andric } 5403ca95b02SDimitry Andric } 5413ca95b02SDimitry Andric 5423ca95b02SDimitry Andric void CodeViewDebug::emitInlinedCallSite(const FunctionInfo &FI, 5433ca95b02SDimitry Andric const DILocation *InlinedAt, 5443ca95b02SDimitry Andric const InlineSite &Site) { 5453ca95b02SDimitry Andric MCSymbol *InlineBegin = MMI->getContext().createTempSymbol(), 5463ca95b02SDimitry Andric *InlineEnd = MMI->getContext().createTempSymbol(); 5473ca95b02SDimitry Andric 5483ca95b02SDimitry Andric assert(TypeIndices.count({Site.Inlinee, nullptr})); 5493ca95b02SDimitry Andric TypeIndex InlineeIdx = TypeIndices[{Site.Inlinee, nullptr}]; 5503ca95b02SDimitry Andric 5513ca95b02SDimitry Andric // SymbolRecord 5523ca95b02SDimitry Andric OS.AddComment("Record length"); 5533ca95b02SDimitry Andric OS.emitAbsoluteSymbolDiff(InlineEnd, InlineBegin, 2); // RecordLength 5543ca95b02SDimitry Andric OS.EmitLabel(InlineBegin); 5553ca95b02SDimitry Andric OS.AddComment("Record kind: S_INLINESITE"); 5563ca95b02SDimitry Andric OS.EmitIntValue(SymbolKind::S_INLINESITE, 2); // RecordKind 5573ca95b02SDimitry Andric 5583ca95b02SDimitry Andric OS.AddComment("PtrParent"); 5593ca95b02SDimitry Andric OS.EmitIntValue(0, 4); 5603ca95b02SDimitry Andric OS.AddComment("PtrEnd"); 5613ca95b02SDimitry Andric OS.EmitIntValue(0, 4); 5623ca95b02SDimitry Andric OS.AddComment("Inlinee type index"); 5633ca95b02SDimitry Andric OS.EmitIntValue(InlineeIdx.getIndex(), 4); 5643ca95b02SDimitry Andric 5653ca95b02SDimitry Andric unsigned FileId = maybeRecordFile(Site.Inlinee->getFile()); 5663ca95b02SDimitry Andric unsigned StartLineNum = Site.Inlinee->getLine(); 5673ca95b02SDimitry Andric SmallVector<unsigned, 3> SecondaryFuncIds; 5683ca95b02SDimitry Andric collectInlineSiteChildren(SecondaryFuncIds, FI, Site); 5693ca95b02SDimitry Andric 5703ca95b02SDimitry Andric OS.EmitCVInlineLinetableDirective(Site.SiteFuncId, FileId, StartLineNum, 5713ca95b02SDimitry Andric FI.Begin, FI.End, SecondaryFuncIds); 5723ca95b02SDimitry Andric 5733ca95b02SDimitry Andric OS.EmitLabel(InlineEnd); 5743ca95b02SDimitry Andric 5753ca95b02SDimitry Andric emitLocalVariableList(Site.InlinedLocals); 5763ca95b02SDimitry Andric 5773ca95b02SDimitry Andric // Recurse on child inlined call sites before closing the scope. 5783ca95b02SDimitry Andric for (const DILocation *ChildSite : Site.ChildSites) { 5793ca95b02SDimitry Andric auto I = FI.InlineSites.find(ChildSite); 5803ca95b02SDimitry Andric assert(I != FI.InlineSites.end() && 5813ca95b02SDimitry Andric "child site not in function inline site map"); 5823ca95b02SDimitry Andric emitInlinedCallSite(FI, ChildSite, I->second); 5833ca95b02SDimitry Andric } 5843ca95b02SDimitry Andric 5853ca95b02SDimitry Andric // Close the scope. 5863ca95b02SDimitry Andric OS.AddComment("Record length"); 5873ca95b02SDimitry Andric OS.EmitIntValue(2, 2); // RecordLength 5883ca95b02SDimitry Andric OS.AddComment("Record kind: S_INLINESITE_END"); 5893ca95b02SDimitry Andric OS.EmitIntValue(SymbolKind::S_INLINESITE_END, 2); // RecordKind 5903ca95b02SDimitry Andric } 5913ca95b02SDimitry Andric 5923ca95b02SDimitry Andric void CodeViewDebug::switchToDebugSectionForSymbol(const MCSymbol *GVSym) { 5933ca95b02SDimitry Andric // If we have a symbol, it may be in a section that is COMDAT. If so, find the 5943ca95b02SDimitry Andric // comdat key. A section may be comdat because of -ffunction-sections or 5953ca95b02SDimitry Andric // because it is comdat in the IR. 5963ca95b02SDimitry Andric MCSectionCOFF *GVSec = 5973ca95b02SDimitry Andric GVSym ? dyn_cast<MCSectionCOFF>(&GVSym->getSection()) : nullptr; 5983ca95b02SDimitry Andric const MCSymbol *KeySym = GVSec ? GVSec->getCOMDATSymbol() : nullptr; 5993ca95b02SDimitry Andric 6003ca95b02SDimitry Andric MCSectionCOFF *DebugSec = cast<MCSectionCOFF>( 6013ca95b02SDimitry Andric Asm->getObjFileLowering().getCOFFDebugSymbolsSection()); 6023ca95b02SDimitry Andric DebugSec = OS.getContext().getAssociativeCOFFSection(DebugSec, KeySym); 6033ca95b02SDimitry Andric 6043ca95b02SDimitry Andric OS.SwitchSection(DebugSec); 6053ca95b02SDimitry Andric 6063ca95b02SDimitry Andric // Emit the magic version number if this is the first time we've switched to 6073ca95b02SDimitry Andric // this section. 6083ca95b02SDimitry Andric if (ComdatDebugSections.insert(DebugSec).second) 6093ca95b02SDimitry Andric emitCodeViewMagicVersion(); 6103ca95b02SDimitry Andric } 6113ca95b02SDimitry Andric 6123ca95b02SDimitry Andric void CodeViewDebug::emitDebugInfoForFunction(const Function *GV, 6133ca95b02SDimitry Andric FunctionInfo &FI) { 6143ca95b02SDimitry Andric // For each function there is a separate subsection 6153ca95b02SDimitry Andric // which holds the PC to file:line table. 6163ca95b02SDimitry Andric const MCSymbol *Fn = Asm->getSymbol(GV); 6173ca95b02SDimitry Andric assert(Fn); 6183ca95b02SDimitry Andric 6193ca95b02SDimitry Andric // Switch to the to a comdat section, if appropriate. 6203ca95b02SDimitry Andric switchToDebugSectionForSymbol(Fn); 6213ca95b02SDimitry Andric 6223ca95b02SDimitry Andric std::string FuncName; 6233ca95b02SDimitry Andric auto *SP = GV->getSubprogram(); 6243ca95b02SDimitry Andric setCurrentSubprogram(SP); 6253ca95b02SDimitry Andric 6263ca95b02SDimitry Andric // If we have a display name, build the fully qualified name by walking the 6273ca95b02SDimitry Andric // chain of scopes. 6283ca95b02SDimitry Andric if (SP != nullptr && !SP->getDisplayName().empty()) 6293ca95b02SDimitry Andric FuncName = 6303ca95b02SDimitry Andric getFullyQualifiedName(SP->getScope().resolve(), SP->getDisplayName()); 6313ca95b02SDimitry Andric 6323ca95b02SDimitry Andric // If our DISubprogram name is empty, use the mangled name. 6333ca95b02SDimitry Andric if (FuncName.empty()) 6343ca95b02SDimitry Andric FuncName = GlobalValue::getRealLinkageName(GV->getName()); 6353ca95b02SDimitry Andric 6363ca95b02SDimitry Andric // Emit a symbol subsection, required by VS2012+ to find function boundaries. 6373ca95b02SDimitry Andric OS.AddComment("Symbol subsection for " + Twine(FuncName)); 6383ca95b02SDimitry Andric MCSymbol *SymbolsEnd = beginCVSubsection(ModuleSubstreamKind::Symbols); 6393ca95b02SDimitry Andric { 6403ca95b02SDimitry Andric MCSymbol *ProcRecordBegin = MMI->getContext().createTempSymbol(), 6413ca95b02SDimitry Andric *ProcRecordEnd = MMI->getContext().createTempSymbol(); 6423ca95b02SDimitry Andric OS.AddComment("Record length"); 6433ca95b02SDimitry Andric OS.emitAbsoluteSymbolDiff(ProcRecordEnd, ProcRecordBegin, 2); 6443ca95b02SDimitry Andric OS.EmitLabel(ProcRecordBegin); 6453ca95b02SDimitry Andric 6463ca95b02SDimitry Andric if (GV->hasLocalLinkage()) { 6473ca95b02SDimitry Andric OS.AddComment("Record kind: S_LPROC32_ID"); 6483ca95b02SDimitry Andric OS.EmitIntValue(unsigned(SymbolKind::S_LPROC32_ID), 2); 6493ca95b02SDimitry Andric } else { 6503ca95b02SDimitry Andric OS.AddComment("Record kind: S_GPROC32_ID"); 6513ca95b02SDimitry Andric OS.EmitIntValue(unsigned(SymbolKind::S_GPROC32_ID), 2); 6523ca95b02SDimitry Andric } 6533ca95b02SDimitry Andric 6543ca95b02SDimitry Andric // These fields are filled in by tools like CVPACK which run after the fact. 6553ca95b02SDimitry Andric OS.AddComment("PtrParent"); 6563ca95b02SDimitry Andric OS.EmitIntValue(0, 4); 6573ca95b02SDimitry Andric OS.AddComment("PtrEnd"); 6583ca95b02SDimitry Andric OS.EmitIntValue(0, 4); 6593ca95b02SDimitry Andric OS.AddComment("PtrNext"); 6603ca95b02SDimitry Andric OS.EmitIntValue(0, 4); 6613ca95b02SDimitry Andric // This is the important bit that tells the debugger where the function 6623ca95b02SDimitry Andric // code is located and what's its size: 6633ca95b02SDimitry Andric OS.AddComment("Code size"); 6643ca95b02SDimitry Andric OS.emitAbsoluteSymbolDiff(FI.End, Fn, 4); 6653ca95b02SDimitry Andric OS.AddComment("Offset after prologue"); 6663ca95b02SDimitry Andric OS.EmitIntValue(0, 4); 6673ca95b02SDimitry Andric OS.AddComment("Offset before epilogue"); 6683ca95b02SDimitry Andric OS.EmitIntValue(0, 4); 6693ca95b02SDimitry Andric OS.AddComment("Function type index"); 6703ca95b02SDimitry Andric OS.EmitIntValue(getFuncIdForSubprogram(GV->getSubprogram()).getIndex(), 4); 6713ca95b02SDimitry Andric OS.AddComment("Function section relative address"); 6723ca95b02SDimitry Andric OS.EmitCOFFSecRel32(Fn); 6733ca95b02SDimitry Andric OS.AddComment("Function section index"); 6743ca95b02SDimitry Andric OS.EmitCOFFSectionIndex(Fn); 6753ca95b02SDimitry Andric OS.AddComment("Flags"); 6763ca95b02SDimitry Andric OS.EmitIntValue(0, 1); 6773ca95b02SDimitry Andric // Emit the function display name as a null-terminated string. 6783ca95b02SDimitry Andric OS.AddComment("Function name"); 6793ca95b02SDimitry Andric // Truncate the name so we won't overflow the record length field. 6803ca95b02SDimitry Andric emitNullTerminatedSymbolName(OS, FuncName); 6813ca95b02SDimitry Andric OS.EmitLabel(ProcRecordEnd); 6823ca95b02SDimitry Andric 6833ca95b02SDimitry Andric emitLocalVariableList(FI.Locals); 6843ca95b02SDimitry Andric 6853ca95b02SDimitry Andric // Emit inlined call site information. Only emit functions inlined directly 6863ca95b02SDimitry Andric // into the parent function. We'll emit the other sites recursively as part 6873ca95b02SDimitry Andric // of their parent inline site. 6883ca95b02SDimitry Andric for (const DILocation *InlinedAt : FI.ChildSites) { 6893ca95b02SDimitry Andric auto I = FI.InlineSites.find(InlinedAt); 6903ca95b02SDimitry Andric assert(I != FI.InlineSites.end() && 6913ca95b02SDimitry Andric "child site not in function inline site map"); 6923ca95b02SDimitry Andric emitInlinedCallSite(FI, InlinedAt, I->second); 6933ca95b02SDimitry Andric } 6943ca95b02SDimitry Andric 6953ca95b02SDimitry Andric if (SP != nullptr) 6963ca95b02SDimitry Andric emitDebugInfoForUDTs(LocalUDTs); 6973ca95b02SDimitry Andric 6983ca95b02SDimitry Andric // We're done with this function. 6993ca95b02SDimitry Andric OS.AddComment("Record length"); 7003ca95b02SDimitry Andric OS.EmitIntValue(0x0002, 2); 7013ca95b02SDimitry Andric OS.AddComment("Record kind: S_PROC_ID_END"); 7023ca95b02SDimitry Andric OS.EmitIntValue(unsigned(SymbolKind::S_PROC_ID_END), 2); 7033ca95b02SDimitry Andric } 7043ca95b02SDimitry Andric endCVSubsection(SymbolsEnd); 7053ca95b02SDimitry Andric 7063ca95b02SDimitry Andric // We have an assembler directive that takes care of the whole line table. 7073ca95b02SDimitry Andric OS.EmitCVLinetableDirective(FI.FuncId, Fn, FI.End); 7083ca95b02SDimitry Andric } 7093ca95b02SDimitry Andric 7103ca95b02SDimitry Andric CodeViewDebug::LocalVarDefRange 7113ca95b02SDimitry Andric CodeViewDebug::createDefRangeMem(uint16_t CVRegister, int Offset) { 7123ca95b02SDimitry Andric LocalVarDefRange DR; 7133ca95b02SDimitry Andric DR.InMemory = -1; 7143ca95b02SDimitry Andric DR.DataOffset = Offset; 7153ca95b02SDimitry Andric assert(DR.DataOffset == Offset && "truncation"); 7163ca95b02SDimitry Andric DR.StructOffset = 0; 7173ca95b02SDimitry Andric DR.CVRegister = CVRegister; 7183ca95b02SDimitry Andric return DR; 7193ca95b02SDimitry Andric } 7203ca95b02SDimitry Andric 7213ca95b02SDimitry Andric CodeViewDebug::LocalVarDefRange 7223ca95b02SDimitry Andric CodeViewDebug::createDefRangeReg(uint16_t CVRegister) { 7233ca95b02SDimitry Andric LocalVarDefRange DR; 7243ca95b02SDimitry Andric DR.InMemory = 0; 7253ca95b02SDimitry Andric DR.DataOffset = 0; 7263ca95b02SDimitry Andric DR.StructOffset = 0; 7273ca95b02SDimitry Andric DR.CVRegister = CVRegister; 7283ca95b02SDimitry Andric return DR; 7293ca95b02SDimitry Andric } 7303ca95b02SDimitry Andric 7313ca95b02SDimitry Andric void CodeViewDebug::collectVariableInfoFromMMITable( 7323ca95b02SDimitry Andric DenseSet<InlinedVariable> &Processed) { 7333ca95b02SDimitry Andric const TargetSubtargetInfo &TSI = Asm->MF->getSubtarget(); 7343ca95b02SDimitry Andric const TargetFrameLowering *TFI = TSI.getFrameLowering(); 7353ca95b02SDimitry Andric const TargetRegisterInfo *TRI = TSI.getRegisterInfo(); 7363ca95b02SDimitry Andric 7373ca95b02SDimitry Andric for (const MachineModuleInfo::VariableDbgInfo &VI : 7383ca95b02SDimitry Andric MMI->getVariableDbgInfo()) { 7393ca95b02SDimitry Andric if (!VI.Var) 7403ca95b02SDimitry Andric continue; 7413ca95b02SDimitry Andric assert(VI.Var->isValidLocationForIntrinsic(VI.Loc) && 7423ca95b02SDimitry Andric "Expected inlined-at fields to agree"); 7433ca95b02SDimitry Andric 7443ca95b02SDimitry Andric Processed.insert(InlinedVariable(VI.Var, VI.Loc->getInlinedAt())); 7453ca95b02SDimitry Andric LexicalScope *Scope = LScopes.findLexicalScope(VI.Loc); 7463ca95b02SDimitry Andric 7473ca95b02SDimitry Andric // If variable scope is not found then skip this variable. 7483ca95b02SDimitry Andric if (!Scope) 7493ca95b02SDimitry Andric continue; 7503ca95b02SDimitry Andric 7513ca95b02SDimitry Andric // Get the frame register used and the offset. 7523ca95b02SDimitry Andric unsigned FrameReg = 0; 7533ca95b02SDimitry Andric int FrameOffset = TFI->getFrameIndexReference(*Asm->MF, VI.Slot, FrameReg); 7543ca95b02SDimitry Andric uint16_t CVReg = TRI->getCodeViewRegNum(FrameReg); 7553ca95b02SDimitry Andric 7563ca95b02SDimitry Andric // Calculate the label ranges. 7573ca95b02SDimitry Andric LocalVarDefRange DefRange = createDefRangeMem(CVReg, FrameOffset); 7583ca95b02SDimitry Andric for (const InsnRange &Range : Scope->getRanges()) { 7593ca95b02SDimitry Andric const MCSymbol *Begin = getLabelBeforeInsn(Range.first); 7603ca95b02SDimitry Andric const MCSymbol *End = getLabelAfterInsn(Range.second); 7613ca95b02SDimitry Andric End = End ? End : Asm->getFunctionEnd(); 7623ca95b02SDimitry Andric DefRange.Ranges.emplace_back(Begin, End); 7633ca95b02SDimitry Andric } 7643ca95b02SDimitry Andric 7653ca95b02SDimitry Andric LocalVariable Var; 7663ca95b02SDimitry Andric Var.DIVar = VI.Var; 7673ca95b02SDimitry Andric Var.DefRanges.emplace_back(std::move(DefRange)); 7683ca95b02SDimitry Andric recordLocalVariable(std::move(Var), VI.Loc->getInlinedAt()); 7693ca95b02SDimitry Andric } 7703ca95b02SDimitry Andric } 7713ca95b02SDimitry Andric 7723ca95b02SDimitry Andric void CodeViewDebug::collectVariableInfo(const DISubprogram *SP) { 7733ca95b02SDimitry Andric DenseSet<InlinedVariable> Processed; 7743ca95b02SDimitry Andric // Grab the variable info that was squirreled away in the MMI side-table. 7753ca95b02SDimitry Andric collectVariableInfoFromMMITable(Processed); 7763ca95b02SDimitry Andric 7773ca95b02SDimitry Andric const TargetRegisterInfo *TRI = Asm->MF->getSubtarget().getRegisterInfo(); 7783ca95b02SDimitry Andric 7793ca95b02SDimitry Andric for (const auto &I : DbgValues) { 7803ca95b02SDimitry Andric InlinedVariable IV = I.first; 7813ca95b02SDimitry Andric if (Processed.count(IV)) 7823ca95b02SDimitry Andric continue; 7833ca95b02SDimitry Andric const DILocalVariable *DIVar = IV.first; 7843ca95b02SDimitry Andric const DILocation *InlinedAt = IV.second; 7853ca95b02SDimitry Andric 7863ca95b02SDimitry Andric // Instruction ranges, specifying where IV is accessible. 7873ca95b02SDimitry Andric const auto &Ranges = I.second; 7883ca95b02SDimitry Andric 7893ca95b02SDimitry Andric LexicalScope *Scope = nullptr; 7903ca95b02SDimitry Andric if (InlinedAt) 7913ca95b02SDimitry Andric Scope = LScopes.findInlinedScope(DIVar->getScope(), InlinedAt); 7923ca95b02SDimitry Andric else 7933ca95b02SDimitry Andric Scope = LScopes.findLexicalScope(DIVar->getScope()); 7943ca95b02SDimitry Andric // If variable scope is not found then skip this variable. 7953ca95b02SDimitry Andric if (!Scope) 7963ca95b02SDimitry Andric continue; 7973ca95b02SDimitry Andric 7983ca95b02SDimitry Andric LocalVariable Var; 7993ca95b02SDimitry Andric Var.DIVar = DIVar; 8003ca95b02SDimitry Andric 8013ca95b02SDimitry Andric // Calculate the definition ranges. 8023ca95b02SDimitry Andric for (auto I = Ranges.begin(), E = Ranges.end(); I != E; ++I) { 8033ca95b02SDimitry Andric const InsnRange &Range = *I; 8043ca95b02SDimitry Andric const MachineInstr *DVInst = Range.first; 8053ca95b02SDimitry Andric assert(DVInst->isDebugValue() && "Invalid History entry"); 8063ca95b02SDimitry Andric const DIExpression *DIExpr = DVInst->getDebugExpression(); 8073ca95b02SDimitry Andric 8083ca95b02SDimitry Andric // Bail if there is a complex DWARF expression for now. 8093ca95b02SDimitry Andric if (DIExpr && DIExpr->getNumElements() > 0) 8103ca95b02SDimitry Andric continue; 8113ca95b02SDimitry Andric 8123ca95b02SDimitry Andric // Bail if operand 0 is not a valid register. This means the variable is a 8133ca95b02SDimitry Andric // simple constant, or is described by a complex expression. 8143ca95b02SDimitry Andric // FIXME: Find a way to represent constant variables, since they are 8153ca95b02SDimitry Andric // relatively common. 8163ca95b02SDimitry Andric unsigned Reg = 8173ca95b02SDimitry Andric DVInst->getOperand(0).isReg() ? DVInst->getOperand(0).getReg() : 0; 8183ca95b02SDimitry Andric if (Reg == 0) 8193ca95b02SDimitry Andric continue; 8203ca95b02SDimitry Andric 8213ca95b02SDimitry Andric // Handle the two cases we can handle: indirect in memory and in register. 8223ca95b02SDimitry Andric bool IsIndirect = DVInst->getOperand(1).isImm(); 8233ca95b02SDimitry Andric unsigned CVReg = TRI->getCodeViewRegNum(DVInst->getOperand(0).getReg()); 8243ca95b02SDimitry Andric { 8253ca95b02SDimitry Andric LocalVarDefRange DefRange; 8263ca95b02SDimitry Andric if (IsIndirect) { 8273ca95b02SDimitry Andric int64_t Offset = DVInst->getOperand(1).getImm(); 8283ca95b02SDimitry Andric DefRange = createDefRangeMem(CVReg, Offset); 8293ca95b02SDimitry Andric } else { 8303ca95b02SDimitry Andric DefRange = createDefRangeReg(CVReg); 8313ca95b02SDimitry Andric } 8323ca95b02SDimitry Andric if (Var.DefRanges.empty() || 8333ca95b02SDimitry Andric Var.DefRanges.back().isDifferentLocation(DefRange)) { 8343ca95b02SDimitry Andric Var.DefRanges.emplace_back(std::move(DefRange)); 8353ca95b02SDimitry Andric } 8363ca95b02SDimitry Andric } 8373ca95b02SDimitry Andric 8383ca95b02SDimitry Andric // Compute the label range. 8393ca95b02SDimitry Andric const MCSymbol *Begin = getLabelBeforeInsn(Range.first); 8403ca95b02SDimitry Andric const MCSymbol *End = getLabelAfterInsn(Range.second); 8413ca95b02SDimitry Andric if (!End) { 8423ca95b02SDimitry Andric if (std::next(I) != E) 8433ca95b02SDimitry Andric End = getLabelBeforeInsn(std::next(I)->first); 8443ca95b02SDimitry Andric else 8453ca95b02SDimitry Andric End = Asm->getFunctionEnd(); 8463ca95b02SDimitry Andric } 8473ca95b02SDimitry Andric 8483ca95b02SDimitry Andric // If the last range end is our begin, just extend the last range. 8493ca95b02SDimitry Andric // Otherwise make a new range. 8503ca95b02SDimitry Andric SmallVectorImpl<std::pair<const MCSymbol *, const MCSymbol *>> &Ranges = 8513ca95b02SDimitry Andric Var.DefRanges.back().Ranges; 8523ca95b02SDimitry Andric if (!Ranges.empty() && Ranges.back().second == Begin) 8533ca95b02SDimitry Andric Ranges.back().second = End; 8543ca95b02SDimitry Andric else 8553ca95b02SDimitry Andric Ranges.emplace_back(Begin, End); 8563ca95b02SDimitry Andric 8573ca95b02SDimitry Andric // FIXME: Do more range combining. 8583ca95b02SDimitry Andric } 8593ca95b02SDimitry Andric 8603ca95b02SDimitry Andric recordLocalVariable(std::move(Var), InlinedAt); 8613ca95b02SDimitry Andric } 8623ca95b02SDimitry Andric } 8633ca95b02SDimitry Andric 8643ca95b02SDimitry Andric void CodeViewDebug::beginFunction(const MachineFunction *MF) { 8653ca95b02SDimitry Andric assert(!CurFn && "Can't process two functions at once!"); 8663ca95b02SDimitry Andric 8673ca95b02SDimitry Andric if (!Asm || !MMI->hasDebugInfo()) 8683ca95b02SDimitry Andric return; 8693ca95b02SDimitry Andric 8703ca95b02SDimitry Andric DebugHandlerBase::beginFunction(MF); 8713ca95b02SDimitry Andric 8723ca95b02SDimitry Andric const Function *GV = MF->getFunction(); 8733ca95b02SDimitry Andric assert(FnDebugInfo.count(GV) == false); 8743ca95b02SDimitry Andric CurFn = &FnDebugInfo[GV]; 8753ca95b02SDimitry Andric CurFn->FuncId = NextFuncId++; 8763ca95b02SDimitry Andric CurFn->Begin = Asm->getFunctionBegin(); 8773ca95b02SDimitry Andric 8783ca95b02SDimitry Andric // Find the end of the function prolog. First known non-DBG_VALUE and 8793ca95b02SDimitry Andric // non-frame setup location marks the beginning of the function body. 8803ca95b02SDimitry Andric // FIXME: is there a simpler a way to do this? Can we just search 8813ca95b02SDimitry Andric // for the first instruction of the function, not the last of the prolog? 8823ca95b02SDimitry Andric DebugLoc PrologEndLoc; 8833ca95b02SDimitry Andric bool EmptyPrologue = true; 8843ca95b02SDimitry Andric for (const auto &MBB : *MF) { 8853ca95b02SDimitry Andric for (const auto &MI : MBB) { 8863ca95b02SDimitry Andric if (!MI.isDebugValue() && !MI.getFlag(MachineInstr::FrameSetup) && 8873ca95b02SDimitry Andric MI.getDebugLoc()) { 8883ca95b02SDimitry Andric PrologEndLoc = MI.getDebugLoc(); 8893ca95b02SDimitry Andric break; 8903ca95b02SDimitry Andric } else if (!MI.isDebugValue()) { 8913ca95b02SDimitry Andric EmptyPrologue = false; 8923ca95b02SDimitry Andric } 8933ca95b02SDimitry Andric } 8943ca95b02SDimitry Andric } 8953ca95b02SDimitry Andric 8963ca95b02SDimitry Andric // Record beginning of function if we have a non-empty prologue. 8973ca95b02SDimitry Andric if (PrologEndLoc && !EmptyPrologue) { 8983ca95b02SDimitry Andric DebugLoc FnStartDL = PrologEndLoc.getFnDebugLoc(); 8993ca95b02SDimitry Andric maybeRecordLocation(FnStartDL, MF); 9003ca95b02SDimitry Andric } 9013ca95b02SDimitry Andric } 9023ca95b02SDimitry Andric 9033ca95b02SDimitry Andric void CodeViewDebug::addToUDTs(const DIType *Ty, TypeIndex TI) { 9043ca95b02SDimitry Andric // Don't record empty UDTs. 9053ca95b02SDimitry Andric if (Ty->getName().empty()) 9063ca95b02SDimitry Andric return; 9073ca95b02SDimitry Andric 9083ca95b02SDimitry Andric SmallVector<StringRef, 5> QualifiedNameComponents; 9093ca95b02SDimitry Andric const DISubprogram *ClosestSubprogram = getQualifiedNameComponents( 9103ca95b02SDimitry Andric Ty->getScope().resolve(), QualifiedNameComponents); 9113ca95b02SDimitry Andric 9123ca95b02SDimitry Andric std::string FullyQualifiedName = 9133ca95b02SDimitry Andric getQualifiedName(QualifiedNameComponents, getPrettyScopeName(Ty)); 9143ca95b02SDimitry Andric 9153ca95b02SDimitry Andric if (ClosestSubprogram == nullptr) 9163ca95b02SDimitry Andric GlobalUDTs.emplace_back(std::move(FullyQualifiedName), TI); 9173ca95b02SDimitry Andric else if (ClosestSubprogram == CurrentSubprogram) 9183ca95b02SDimitry Andric LocalUDTs.emplace_back(std::move(FullyQualifiedName), TI); 9193ca95b02SDimitry Andric 9203ca95b02SDimitry Andric // TODO: What if the ClosestSubprogram is neither null or the current 9213ca95b02SDimitry Andric // subprogram? Currently, the UDT just gets dropped on the floor. 9223ca95b02SDimitry Andric // 9233ca95b02SDimitry Andric // The current behavior is not desirable. To get maximal fidelity, we would 9243ca95b02SDimitry Andric // need to perform all type translation before beginning emission of .debug$S 9253ca95b02SDimitry Andric // and then make LocalUDTs a member of FunctionInfo 9263ca95b02SDimitry Andric } 9273ca95b02SDimitry Andric 9283ca95b02SDimitry Andric TypeIndex CodeViewDebug::lowerType(const DIType *Ty, const DIType *ClassTy) { 9293ca95b02SDimitry Andric // Generic dispatch for lowering an unknown type. 9303ca95b02SDimitry Andric switch (Ty->getTag()) { 9313ca95b02SDimitry Andric case dwarf::DW_TAG_array_type: 9323ca95b02SDimitry Andric return lowerTypeArray(cast<DICompositeType>(Ty)); 9333ca95b02SDimitry Andric case dwarf::DW_TAG_typedef: 9343ca95b02SDimitry Andric return lowerTypeAlias(cast<DIDerivedType>(Ty)); 9353ca95b02SDimitry Andric case dwarf::DW_TAG_base_type: 9363ca95b02SDimitry Andric return lowerTypeBasic(cast<DIBasicType>(Ty)); 9373ca95b02SDimitry Andric case dwarf::DW_TAG_pointer_type: 9383ca95b02SDimitry Andric case dwarf::DW_TAG_reference_type: 9393ca95b02SDimitry Andric case dwarf::DW_TAG_rvalue_reference_type: 9403ca95b02SDimitry Andric return lowerTypePointer(cast<DIDerivedType>(Ty)); 9413ca95b02SDimitry Andric case dwarf::DW_TAG_ptr_to_member_type: 9423ca95b02SDimitry Andric return lowerTypeMemberPointer(cast<DIDerivedType>(Ty)); 9433ca95b02SDimitry Andric case dwarf::DW_TAG_const_type: 9443ca95b02SDimitry Andric case dwarf::DW_TAG_volatile_type: 9453ca95b02SDimitry Andric return lowerTypeModifier(cast<DIDerivedType>(Ty)); 9463ca95b02SDimitry Andric case dwarf::DW_TAG_subroutine_type: 9473ca95b02SDimitry Andric if (ClassTy) { 9483ca95b02SDimitry Andric // The member function type of a member function pointer has no 9493ca95b02SDimitry Andric // ThisAdjustment. 9503ca95b02SDimitry Andric return lowerTypeMemberFunction(cast<DISubroutineType>(Ty), ClassTy, 9513ca95b02SDimitry Andric /*ThisAdjustment=*/0); 9523ca95b02SDimitry Andric } 9533ca95b02SDimitry Andric return lowerTypeFunction(cast<DISubroutineType>(Ty)); 9543ca95b02SDimitry Andric case dwarf::DW_TAG_enumeration_type: 9553ca95b02SDimitry Andric return lowerTypeEnum(cast<DICompositeType>(Ty)); 9563ca95b02SDimitry Andric case dwarf::DW_TAG_class_type: 9573ca95b02SDimitry Andric case dwarf::DW_TAG_structure_type: 9583ca95b02SDimitry Andric return lowerTypeClass(cast<DICompositeType>(Ty)); 9593ca95b02SDimitry Andric case dwarf::DW_TAG_union_type: 9603ca95b02SDimitry Andric return lowerTypeUnion(cast<DICompositeType>(Ty)); 9613ca95b02SDimitry Andric default: 9623ca95b02SDimitry Andric // Use the null type index. 9633ca95b02SDimitry Andric return TypeIndex(); 9643ca95b02SDimitry Andric } 9653ca95b02SDimitry Andric } 9663ca95b02SDimitry Andric 9673ca95b02SDimitry Andric TypeIndex CodeViewDebug::lowerTypeAlias(const DIDerivedType *Ty) { 9683ca95b02SDimitry Andric DITypeRef UnderlyingTypeRef = Ty->getBaseType(); 9693ca95b02SDimitry Andric TypeIndex UnderlyingTypeIndex = getTypeIndex(UnderlyingTypeRef); 9703ca95b02SDimitry Andric StringRef TypeName = Ty->getName(); 9713ca95b02SDimitry Andric 9723ca95b02SDimitry Andric addToUDTs(Ty, UnderlyingTypeIndex); 9733ca95b02SDimitry Andric 9743ca95b02SDimitry Andric if (UnderlyingTypeIndex == TypeIndex(SimpleTypeKind::Int32Long) && 9753ca95b02SDimitry Andric TypeName == "HRESULT") 9763ca95b02SDimitry Andric return TypeIndex(SimpleTypeKind::HResult); 9773ca95b02SDimitry Andric if (UnderlyingTypeIndex == TypeIndex(SimpleTypeKind::UInt16Short) && 9783ca95b02SDimitry Andric TypeName == "wchar_t") 9793ca95b02SDimitry Andric return TypeIndex(SimpleTypeKind::WideCharacter); 9803ca95b02SDimitry Andric 9813ca95b02SDimitry Andric return UnderlyingTypeIndex; 9823ca95b02SDimitry Andric } 9833ca95b02SDimitry Andric 9843ca95b02SDimitry Andric TypeIndex CodeViewDebug::lowerTypeArray(const DICompositeType *Ty) { 9853ca95b02SDimitry Andric DITypeRef ElementTypeRef = Ty->getBaseType(); 9863ca95b02SDimitry Andric TypeIndex ElementTypeIndex = getTypeIndex(ElementTypeRef); 9873ca95b02SDimitry Andric // IndexType is size_t, which depends on the bitness of the target. 9883ca95b02SDimitry Andric TypeIndex IndexType = Asm->MAI->getPointerSize() == 8 9893ca95b02SDimitry Andric ? TypeIndex(SimpleTypeKind::UInt64Quad) 9903ca95b02SDimitry Andric : TypeIndex(SimpleTypeKind::UInt32Long); 9913ca95b02SDimitry Andric 9923ca95b02SDimitry Andric uint64_t ElementSize = getBaseTypeSize(ElementTypeRef) / 8; 9933ca95b02SDimitry Andric 9943ca95b02SDimitry Andric bool UndefinedSubrange = false; 9953ca95b02SDimitry Andric 9963ca95b02SDimitry Andric // FIXME: 9973ca95b02SDimitry Andric // There is a bug in the front-end where an array of a structure, which was 9983ca95b02SDimitry Andric // declared as incomplete structure first, ends up not getting a size assigned 9993ca95b02SDimitry Andric // to it. (PR28303) 10003ca95b02SDimitry Andric // Example: 10013ca95b02SDimitry Andric // struct A(*p)[3]; 10023ca95b02SDimitry Andric // struct A { int f; } a[3]; 10033ca95b02SDimitry Andric // 10043ca95b02SDimitry Andric // This needs to be fixed in the front-end, but in the meantime we don't want 10053ca95b02SDimitry Andric // to trigger an assertion because of this. 10063ca95b02SDimitry Andric if (Ty->getSizeInBits() == 0) { 10073ca95b02SDimitry Andric UndefinedSubrange = true; 10083ca95b02SDimitry Andric } 10093ca95b02SDimitry Andric 10103ca95b02SDimitry Andric // Add subranges to array type. 10113ca95b02SDimitry Andric DINodeArray Elements = Ty->getElements(); 10123ca95b02SDimitry Andric for (int i = Elements.size() - 1; i >= 0; --i) { 10133ca95b02SDimitry Andric const DINode *Element = Elements[i]; 10143ca95b02SDimitry Andric assert(Element->getTag() == dwarf::DW_TAG_subrange_type); 10153ca95b02SDimitry Andric 10163ca95b02SDimitry Andric const DISubrange *Subrange = cast<DISubrange>(Element); 10173ca95b02SDimitry Andric assert(Subrange->getLowerBound() == 0 && 10183ca95b02SDimitry Andric "codeview doesn't support subranges with lower bounds"); 10193ca95b02SDimitry Andric int64_t Count = Subrange->getCount(); 10203ca95b02SDimitry Andric 10213ca95b02SDimitry Andric // Variable Length Array (VLA) has Count equal to '-1'. 10223ca95b02SDimitry Andric // Replace with Count '1', assume it is the minimum VLA length. 10233ca95b02SDimitry Andric // FIXME: Make front-end support VLA subrange and emit LF_DIMVARLU. 10243ca95b02SDimitry Andric if (Count == -1) { 10253ca95b02SDimitry Andric Count = 1; 10263ca95b02SDimitry Andric UndefinedSubrange = true; 10273ca95b02SDimitry Andric } 10283ca95b02SDimitry Andric 10293ca95b02SDimitry Andric StringRef Name = (i == 0) ? Ty->getName() : ""; 10303ca95b02SDimitry Andric // Update the element size and element type index for subsequent subranges. 10313ca95b02SDimitry Andric ElementSize *= Count; 10323ca95b02SDimitry Andric ElementTypeIndex = TypeTable.writeArray( 10333ca95b02SDimitry Andric ArrayRecord(ElementTypeIndex, IndexType, ElementSize, Name)); 10343ca95b02SDimitry Andric } 10353ca95b02SDimitry Andric 10363ca95b02SDimitry Andric (void)UndefinedSubrange; 10373ca95b02SDimitry Andric assert(UndefinedSubrange || ElementSize == (Ty->getSizeInBits() / 8)); 10383ca95b02SDimitry Andric 10393ca95b02SDimitry Andric return ElementTypeIndex; 10403ca95b02SDimitry Andric } 10413ca95b02SDimitry Andric 10423ca95b02SDimitry Andric TypeIndex CodeViewDebug::lowerTypeBasic(const DIBasicType *Ty) { 10433ca95b02SDimitry Andric TypeIndex Index; 10443ca95b02SDimitry Andric dwarf::TypeKind Kind; 10453ca95b02SDimitry Andric uint32_t ByteSize; 10463ca95b02SDimitry Andric 10473ca95b02SDimitry Andric Kind = static_cast<dwarf::TypeKind>(Ty->getEncoding()); 10483ca95b02SDimitry Andric ByteSize = Ty->getSizeInBits() / 8; 10493ca95b02SDimitry Andric 10503ca95b02SDimitry Andric SimpleTypeKind STK = SimpleTypeKind::None; 10513ca95b02SDimitry Andric switch (Kind) { 10523ca95b02SDimitry Andric case dwarf::DW_ATE_address: 10533ca95b02SDimitry Andric // FIXME: Translate 10543ca95b02SDimitry Andric break; 10553ca95b02SDimitry Andric case dwarf::DW_ATE_boolean: 10563ca95b02SDimitry Andric switch (ByteSize) { 10573ca95b02SDimitry Andric case 1: STK = SimpleTypeKind::Boolean8; break; 10583ca95b02SDimitry Andric case 2: STK = SimpleTypeKind::Boolean16; break; 10593ca95b02SDimitry Andric case 4: STK = SimpleTypeKind::Boolean32; break; 10603ca95b02SDimitry Andric case 8: STK = SimpleTypeKind::Boolean64; break; 10613ca95b02SDimitry Andric case 16: STK = SimpleTypeKind::Boolean128; break; 10623ca95b02SDimitry Andric } 10633ca95b02SDimitry Andric break; 10643ca95b02SDimitry Andric case dwarf::DW_ATE_complex_float: 10653ca95b02SDimitry Andric switch (ByteSize) { 10663ca95b02SDimitry Andric case 2: STK = SimpleTypeKind::Complex16; break; 10673ca95b02SDimitry Andric case 4: STK = SimpleTypeKind::Complex32; break; 10683ca95b02SDimitry Andric case 8: STK = SimpleTypeKind::Complex64; break; 10693ca95b02SDimitry Andric case 10: STK = SimpleTypeKind::Complex80; break; 10703ca95b02SDimitry Andric case 16: STK = SimpleTypeKind::Complex128; break; 10713ca95b02SDimitry Andric } 10723ca95b02SDimitry Andric break; 10733ca95b02SDimitry Andric case dwarf::DW_ATE_float: 10743ca95b02SDimitry Andric switch (ByteSize) { 10753ca95b02SDimitry Andric case 2: STK = SimpleTypeKind::Float16; break; 10763ca95b02SDimitry Andric case 4: STK = SimpleTypeKind::Float32; break; 10773ca95b02SDimitry Andric case 6: STK = SimpleTypeKind::Float48; break; 10783ca95b02SDimitry Andric case 8: STK = SimpleTypeKind::Float64; break; 10793ca95b02SDimitry Andric case 10: STK = SimpleTypeKind::Float80; break; 10803ca95b02SDimitry Andric case 16: STK = SimpleTypeKind::Float128; break; 10813ca95b02SDimitry Andric } 10823ca95b02SDimitry Andric break; 10833ca95b02SDimitry Andric case dwarf::DW_ATE_signed: 10843ca95b02SDimitry Andric switch (ByteSize) { 10853ca95b02SDimitry Andric case 1: STK = SimpleTypeKind::SByte; break; 10863ca95b02SDimitry Andric case 2: STK = SimpleTypeKind::Int16Short; break; 10873ca95b02SDimitry Andric case 4: STK = SimpleTypeKind::Int32; break; 10883ca95b02SDimitry Andric case 8: STK = SimpleTypeKind::Int64Quad; break; 10893ca95b02SDimitry Andric case 16: STK = SimpleTypeKind::Int128Oct; break; 10903ca95b02SDimitry Andric } 10913ca95b02SDimitry Andric break; 10923ca95b02SDimitry Andric case dwarf::DW_ATE_unsigned: 10933ca95b02SDimitry Andric switch (ByteSize) { 10943ca95b02SDimitry Andric case 1: STK = SimpleTypeKind::Byte; break; 10953ca95b02SDimitry Andric case 2: STK = SimpleTypeKind::UInt16Short; break; 10963ca95b02SDimitry Andric case 4: STK = SimpleTypeKind::UInt32; break; 10973ca95b02SDimitry Andric case 8: STK = SimpleTypeKind::UInt64Quad; break; 10983ca95b02SDimitry Andric case 16: STK = SimpleTypeKind::UInt128Oct; break; 10993ca95b02SDimitry Andric } 11003ca95b02SDimitry Andric break; 11013ca95b02SDimitry Andric case dwarf::DW_ATE_UTF: 11023ca95b02SDimitry Andric switch (ByteSize) { 11033ca95b02SDimitry Andric case 2: STK = SimpleTypeKind::Character16; break; 11043ca95b02SDimitry Andric case 4: STK = SimpleTypeKind::Character32; break; 11053ca95b02SDimitry Andric } 11063ca95b02SDimitry Andric break; 11073ca95b02SDimitry Andric case dwarf::DW_ATE_signed_char: 11083ca95b02SDimitry Andric if (ByteSize == 1) 11093ca95b02SDimitry Andric STK = SimpleTypeKind::SignedCharacter; 11103ca95b02SDimitry Andric break; 11113ca95b02SDimitry Andric case dwarf::DW_ATE_unsigned_char: 11123ca95b02SDimitry Andric if (ByteSize == 1) 11133ca95b02SDimitry Andric STK = SimpleTypeKind::UnsignedCharacter; 11143ca95b02SDimitry Andric break; 11153ca95b02SDimitry Andric default: 11163ca95b02SDimitry Andric break; 11173ca95b02SDimitry Andric } 11183ca95b02SDimitry Andric 11193ca95b02SDimitry Andric // Apply some fixups based on the source-level type name. 11203ca95b02SDimitry Andric if (STK == SimpleTypeKind::Int32 && Ty->getName() == "long int") 11213ca95b02SDimitry Andric STK = SimpleTypeKind::Int32Long; 11223ca95b02SDimitry Andric if (STK == SimpleTypeKind::UInt32 && Ty->getName() == "long unsigned int") 11233ca95b02SDimitry Andric STK = SimpleTypeKind::UInt32Long; 11243ca95b02SDimitry Andric if (STK == SimpleTypeKind::UInt16Short && 11253ca95b02SDimitry Andric (Ty->getName() == "wchar_t" || Ty->getName() == "__wchar_t")) 11263ca95b02SDimitry Andric STK = SimpleTypeKind::WideCharacter; 11273ca95b02SDimitry Andric if ((STK == SimpleTypeKind::SignedCharacter || 11283ca95b02SDimitry Andric STK == SimpleTypeKind::UnsignedCharacter) && 11293ca95b02SDimitry Andric Ty->getName() == "char") 11303ca95b02SDimitry Andric STK = SimpleTypeKind::NarrowCharacter; 11313ca95b02SDimitry Andric 11323ca95b02SDimitry Andric return TypeIndex(STK); 11333ca95b02SDimitry Andric } 11343ca95b02SDimitry Andric 11353ca95b02SDimitry Andric TypeIndex CodeViewDebug::lowerTypePointer(const DIDerivedType *Ty) { 11363ca95b02SDimitry Andric TypeIndex PointeeTI = getTypeIndex(Ty->getBaseType()); 11373ca95b02SDimitry Andric 11383ca95b02SDimitry Andric // While processing the type being pointed to it is possible we already 11393ca95b02SDimitry Andric // created this pointer type. If so, we check here and return the existing 11403ca95b02SDimitry Andric // pointer type. 11413ca95b02SDimitry Andric auto I = TypeIndices.find({Ty, nullptr}); 11423ca95b02SDimitry Andric if (I != TypeIndices.end()) 11433ca95b02SDimitry Andric return I->second; 11443ca95b02SDimitry Andric 11453ca95b02SDimitry Andric // Pointers to simple types can use SimpleTypeMode, rather than having a 11463ca95b02SDimitry Andric // dedicated pointer type record. 11473ca95b02SDimitry Andric if (PointeeTI.isSimple() && 11483ca95b02SDimitry Andric PointeeTI.getSimpleMode() == SimpleTypeMode::Direct && 11493ca95b02SDimitry Andric Ty->getTag() == dwarf::DW_TAG_pointer_type) { 11503ca95b02SDimitry Andric SimpleTypeMode Mode = Ty->getSizeInBits() == 64 11513ca95b02SDimitry Andric ? SimpleTypeMode::NearPointer64 11523ca95b02SDimitry Andric : SimpleTypeMode::NearPointer32; 11533ca95b02SDimitry Andric return TypeIndex(PointeeTI.getSimpleKind(), Mode); 11543ca95b02SDimitry Andric } 11553ca95b02SDimitry Andric 11563ca95b02SDimitry Andric PointerKind PK = 11573ca95b02SDimitry Andric Ty->getSizeInBits() == 64 ? PointerKind::Near64 : PointerKind::Near32; 11583ca95b02SDimitry Andric PointerMode PM = PointerMode::Pointer; 11593ca95b02SDimitry Andric switch (Ty->getTag()) { 11603ca95b02SDimitry Andric default: llvm_unreachable("not a pointer tag type"); 11613ca95b02SDimitry Andric case dwarf::DW_TAG_pointer_type: 11623ca95b02SDimitry Andric PM = PointerMode::Pointer; 11633ca95b02SDimitry Andric break; 11643ca95b02SDimitry Andric case dwarf::DW_TAG_reference_type: 11653ca95b02SDimitry Andric PM = PointerMode::LValueReference; 11663ca95b02SDimitry Andric break; 11673ca95b02SDimitry Andric case dwarf::DW_TAG_rvalue_reference_type: 11683ca95b02SDimitry Andric PM = PointerMode::RValueReference; 11693ca95b02SDimitry Andric break; 11703ca95b02SDimitry Andric } 11713ca95b02SDimitry Andric // FIXME: MSVC folds qualifiers into PointerOptions in the context of a method 11723ca95b02SDimitry Andric // 'this' pointer, but not normal contexts. Figure out what we're supposed to 11733ca95b02SDimitry Andric // do. 11743ca95b02SDimitry Andric PointerOptions PO = PointerOptions::None; 11753ca95b02SDimitry Andric PointerRecord PR(PointeeTI, PK, PM, PO, Ty->getSizeInBits() / 8); 11763ca95b02SDimitry Andric return TypeTable.writePointer(PR); 11773ca95b02SDimitry Andric } 11783ca95b02SDimitry Andric 11793ca95b02SDimitry Andric static PointerToMemberRepresentation 11803ca95b02SDimitry Andric translatePtrToMemberRep(unsigned SizeInBytes, bool IsPMF, unsigned Flags) { 11813ca95b02SDimitry Andric // SizeInBytes being zero generally implies that the member pointer type was 11823ca95b02SDimitry Andric // incomplete, which can happen if it is part of a function prototype. In this 11833ca95b02SDimitry Andric // case, use the unknown model instead of the general model. 11843ca95b02SDimitry Andric if (IsPMF) { 11853ca95b02SDimitry Andric switch (Flags & DINode::FlagPtrToMemberRep) { 11863ca95b02SDimitry Andric case 0: 11873ca95b02SDimitry Andric return SizeInBytes == 0 ? PointerToMemberRepresentation::Unknown 11883ca95b02SDimitry Andric : PointerToMemberRepresentation::GeneralFunction; 11893ca95b02SDimitry Andric case DINode::FlagSingleInheritance: 11903ca95b02SDimitry Andric return PointerToMemberRepresentation::SingleInheritanceFunction; 11913ca95b02SDimitry Andric case DINode::FlagMultipleInheritance: 11923ca95b02SDimitry Andric return PointerToMemberRepresentation::MultipleInheritanceFunction; 11933ca95b02SDimitry Andric case DINode::FlagVirtualInheritance: 11943ca95b02SDimitry Andric return PointerToMemberRepresentation::VirtualInheritanceFunction; 11953ca95b02SDimitry Andric } 11963ca95b02SDimitry Andric } else { 11973ca95b02SDimitry Andric switch (Flags & DINode::FlagPtrToMemberRep) { 11983ca95b02SDimitry Andric case 0: 11993ca95b02SDimitry Andric return SizeInBytes == 0 ? PointerToMemberRepresentation::Unknown 12003ca95b02SDimitry Andric : PointerToMemberRepresentation::GeneralData; 12013ca95b02SDimitry Andric case DINode::FlagSingleInheritance: 12023ca95b02SDimitry Andric return PointerToMemberRepresentation::SingleInheritanceData; 12033ca95b02SDimitry Andric case DINode::FlagMultipleInheritance: 12043ca95b02SDimitry Andric return PointerToMemberRepresentation::MultipleInheritanceData; 12053ca95b02SDimitry Andric case DINode::FlagVirtualInheritance: 12063ca95b02SDimitry Andric return PointerToMemberRepresentation::VirtualInheritanceData; 12073ca95b02SDimitry Andric } 12083ca95b02SDimitry Andric } 12093ca95b02SDimitry Andric llvm_unreachable("invalid ptr to member representation"); 12103ca95b02SDimitry Andric } 12113ca95b02SDimitry Andric 12123ca95b02SDimitry Andric TypeIndex CodeViewDebug::lowerTypeMemberPointer(const DIDerivedType *Ty) { 12133ca95b02SDimitry Andric assert(Ty->getTag() == dwarf::DW_TAG_ptr_to_member_type); 12143ca95b02SDimitry Andric TypeIndex ClassTI = getTypeIndex(Ty->getClassType()); 12153ca95b02SDimitry Andric TypeIndex PointeeTI = getTypeIndex(Ty->getBaseType(), Ty->getClassType()); 12163ca95b02SDimitry Andric PointerKind PK = Asm->MAI->getPointerSize() == 8 ? PointerKind::Near64 12173ca95b02SDimitry Andric : PointerKind::Near32; 12183ca95b02SDimitry Andric bool IsPMF = isa<DISubroutineType>(Ty->getBaseType()); 12193ca95b02SDimitry Andric PointerMode PM = IsPMF ? PointerMode::PointerToMemberFunction 12203ca95b02SDimitry Andric : PointerMode::PointerToDataMember; 12213ca95b02SDimitry Andric PointerOptions PO = PointerOptions::None; // FIXME 12223ca95b02SDimitry Andric assert(Ty->getSizeInBits() / 8 <= 0xff && "pointer size too big"); 12233ca95b02SDimitry Andric uint8_t SizeInBytes = Ty->getSizeInBits() / 8; 12243ca95b02SDimitry Andric MemberPointerInfo MPI( 12253ca95b02SDimitry Andric ClassTI, translatePtrToMemberRep(SizeInBytes, IsPMF, Ty->getFlags())); 12263ca95b02SDimitry Andric PointerRecord PR(PointeeTI, PK, PM, PO, SizeInBytes, MPI); 12273ca95b02SDimitry Andric return TypeTable.writePointer(PR); 12283ca95b02SDimitry Andric } 12293ca95b02SDimitry Andric 12303ca95b02SDimitry Andric /// Given a DWARF calling convention, get the CodeView equivalent. If we don't 12313ca95b02SDimitry Andric /// have a translation, use the NearC convention. 12323ca95b02SDimitry Andric static CallingConvention dwarfCCToCodeView(unsigned DwarfCC) { 12333ca95b02SDimitry Andric switch (DwarfCC) { 12343ca95b02SDimitry Andric case dwarf::DW_CC_normal: return CallingConvention::NearC; 12353ca95b02SDimitry Andric case dwarf::DW_CC_BORLAND_msfastcall: return CallingConvention::NearFast; 12363ca95b02SDimitry Andric case dwarf::DW_CC_BORLAND_thiscall: return CallingConvention::ThisCall; 12373ca95b02SDimitry Andric case dwarf::DW_CC_BORLAND_stdcall: return CallingConvention::NearStdCall; 12383ca95b02SDimitry Andric case dwarf::DW_CC_BORLAND_pascal: return CallingConvention::NearPascal; 12393ca95b02SDimitry Andric case dwarf::DW_CC_LLVM_vectorcall: return CallingConvention::NearVector; 12403ca95b02SDimitry Andric } 12413ca95b02SDimitry Andric return CallingConvention::NearC; 12423ca95b02SDimitry Andric } 12433ca95b02SDimitry Andric 12443ca95b02SDimitry Andric TypeIndex CodeViewDebug::lowerTypeModifier(const DIDerivedType *Ty) { 12453ca95b02SDimitry Andric ModifierOptions Mods = ModifierOptions::None; 12463ca95b02SDimitry Andric bool IsModifier = true; 12473ca95b02SDimitry Andric const DIType *BaseTy = Ty; 12483ca95b02SDimitry Andric while (IsModifier && BaseTy) { 12493ca95b02SDimitry Andric // FIXME: Need to add DWARF tag for __unaligned. 12503ca95b02SDimitry Andric switch (BaseTy->getTag()) { 12513ca95b02SDimitry Andric case dwarf::DW_TAG_const_type: 12523ca95b02SDimitry Andric Mods |= ModifierOptions::Const; 12533ca95b02SDimitry Andric break; 12543ca95b02SDimitry Andric case dwarf::DW_TAG_volatile_type: 12553ca95b02SDimitry Andric Mods |= ModifierOptions::Volatile; 12563ca95b02SDimitry Andric break; 12573ca95b02SDimitry Andric default: 12583ca95b02SDimitry Andric IsModifier = false; 12593ca95b02SDimitry Andric break; 12603ca95b02SDimitry Andric } 12613ca95b02SDimitry Andric if (IsModifier) 12623ca95b02SDimitry Andric BaseTy = cast<DIDerivedType>(BaseTy)->getBaseType().resolve(); 12633ca95b02SDimitry Andric } 12643ca95b02SDimitry Andric TypeIndex ModifiedTI = getTypeIndex(BaseTy); 12653ca95b02SDimitry Andric 12663ca95b02SDimitry Andric // While processing the type being pointed to, it is possible we already 12673ca95b02SDimitry Andric // created this modifier type. If so, we check here and return the existing 12683ca95b02SDimitry Andric // modifier type. 12693ca95b02SDimitry Andric auto I = TypeIndices.find({Ty, nullptr}); 12703ca95b02SDimitry Andric if (I != TypeIndices.end()) 12713ca95b02SDimitry Andric return I->second; 12723ca95b02SDimitry Andric 12733ca95b02SDimitry Andric ModifierRecord MR(ModifiedTI, Mods); 12743ca95b02SDimitry Andric return TypeTable.writeModifier(MR); 12753ca95b02SDimitry Andric } 12763ca95b02SDimitry Andric 12773ca95b02SDimitry Andric TypeIndex CodeViewDebug::lowerTypeFunction(const DISubroutineType *Ty) { 12783ca95b02SDimitry Andric SmallVector<TypeIndex, 8> ReturnAndArgTypeIndices; 12793ca95b02SDimitry Andric for (DITypeRef ArgTypeRef : Ty->getTypeArray()) 12803ca95b02SDimitry Andric ReturnAndArgTypeIndices.push_back(getTypeIndex(ArgTypeRef)); 12813ca95b02SDimitry Andric 12823ca95b02SDimitry Andric TypeIndex ReturnTypeIndex = TypeIndex::Void(); 12833ca95b02SDimitry Andric ArrayRef<TypeIndex> ArgTypeIndices = None; 12843ca95b02SDimitry Andric if (!ReturnAndArgTypeIndices.empty()) { 12853ca95b02SDimitry Andric auto ReturnAndArgTypesRef = makeArrayRef(ReturnAndArgTypeIndices); 12863ca95b02SDimitry Andric ReturnTypeIndex = ReturnAndArgTypesRef.front(); 12873ca95b02SDimitry Andric ArgTypeIndices = ReturnAndArgTypesRef.drop_front(); 12883ca95b02SDimitry Andric } 12893ca95b02SDimitry Andric 12903ca95b02SDimitry Andric ArgListRecord ArgListRec(TypeRecordKind::ArgList, ArgTypeIndices); 12913ca95b02SDimitry Andric TypeIndex ArgListIndex = TypeTable.writeArgList(ArgListRec); 12923ca95b02SDimitry Andric 12933ca95b02SDimitry Andric CallingConvention CC = dwarfCCToCodeView(Ty->getCC()); 12943ca95b02SDimitry Andric 12953ca95b02SDimitry Andric ProcedureRecord Procedure(ReturnTypeIndex, CC, FunctionOptions::None, 12963ca95b02SDimitry Andric ArgTypeIndices.size(), ArgListIndex); 12973ca95b02SDimitry Andric return TypeTable.writeProcedure(Procedure); 12983ca95b02SDimitry Andric } 12993ca95b02SDimitry Andric 13003ca95b02SDimitry Andric TypeIndex CodeViewDebug::lowerTypeMemberFunction(const DISubroutineType *Ty, 13013ca95b02SDimitry Andric const DIType *ClassTy, 13023ca95b02SDimitry Andric int ThisAdjustment) { 13033ca95b02SDimitry Andric // Lower the containing class type. 13043ca95b02SDimitry Andric TypeIndex ClassType = getTypeIndex(ClassTy); 13053ca95b02SDimitry Andric 13063ca95b02SDimitry Andric SmallVector<TypeIndex, 8> ReturnAndArgTypeIndices; 13073ca95b02SDimitry Andric for (DITypeRef ArgTypeRef : Ty->getTypeArray()) 13083ca95b02SDimitry Andric ReturnAndArgTypeIndices.push_back(getTypeIndex(ArgTypeRef)); 13093ca95b02SDimitry Andric 13103ca95b02SDimitry Andric TypeIndex ReturnTypeIndex = TypeIndex::Void(); 13113ca95b02SDimitry Andric ArrayRef<TypeIndex> ArgTypeIndices = None; 13123ca95b02SDimitry Andric if (!ReturnAndArgTypeIndices.empty()) { 13133ca95b02SDimitry Andric auto ReturnAndArgTypesRef = makeArrayRef(ReturnAndArgTypeIndices); 13143ca95b02SDimitry Andric ReturnTypeIndex = ReturnAndArgTypesRef.front(); 13153ca95b02SDimitry Andric ArgTypeIndices = ReturnAndArgTypesRef.drop_front(); 13163ca95b02SDimitry Andric } 13173ca95b02SDimitry Andric TypeIndex ThisTypeIndex = TypeIndex::Void(); 13183ca95b02SDimitry Andric if (!ArgTypeIndices.empty()) { 13193ca95b02SDimitry Andric ThisTypeIndex = ArgTypeIndices.front(); 13203ca95b02SDimitry Andric ArgTypeIndices = ArgTypeIndices.drop_front(); 13213ca95b02SDimitry Andric } 13223ca95b02SDimitry Andric 13233ca95b02SDimitry Andric ArgListRecord ArgListRec(TypeRecordKind::ArgList, ArgTypeIndices); 13243ca95b02SDimitry Andric TypeIndex ArgListIndex = TypeTable.writeArgList(ArgListRec); 13253ca95b02SDimitry Andric 13263ca95b02SDimitry Andric CallingConvention CC = dwarfCCToCodeView(Ty->getCC()); 13273ca95b02SDimitry Andric 13283ca95b02SDimitry Andric // TODO: Need to use the correct values for: 13293ca95b02SDimitry Andric // FunctionOptions 13303ca95b02SDimitry Andric // ThisPointerAdjustment. 13313ca95b02SDimitry Andric TypeIndex TI = TypeTable.writeMemberFunction(MemberFunctionRecord( 13323ca95b02SDimitry Andric ReturnTypeIndex, ClassType, ThisTypeIndex, CC, FunctionOptions::None, 13333ca95b02SDimitry Andric ArgTypeIndices.size(), ArgListIndex, ThisAdjustment)); 13343ca95b02SDimitry Andric 13353ca95b02SDimitry Andric return TI; 13363ca95b02SDimitry Andric } 13373ca95b02SDimitry Andric 13383ca95b02SDimitry Andric static MemberAccess translateAccessFlags(unsigned RecordTag, unsigned Flags) { 13393ca95b02SDimitry Andric switch (Flags & DINode::FlagAccessibility) { 13403ca95b02SDimitry Andric case DINode::FlagPrivate: return MemberAccess::Private; 13413ca95b02SDimitry Andric case DINode::FlagPublic: return MemberAccess::Public; 13423ca95b02SDimitry Andric case DINode::FlagProtected: return MemberAccess::Protected; 13433ca95b02SDimitry Andric case 0: 13443ca95b02SDimitry Andric // If there was no explicit access control, provide the default for the tag. 13453ca95b02SDimitry Andric return RecordTag == dwarf::DW_TAG_class_type ? MemberAccess::Private 13463ca95b02SDimitry Andric : MemberAccess::Public; 13473ca95b02SDimitry Andric } 13483ca95b02SDimitry Andric llvm_unreachable("access flags are exclusive"); 13493ca95b02SDimitry Andric } 13503ca95b02SDimitry Andric 13513ca95b02SDimitry Andric static MethodOptions translateMethodOptionFlags(const DISubprogram *SP) { 13523ca95b02SDimitry Andric if (SP->isArtificial()) 13533ca95b02SDimitry Andric return MethodOptions::CompilerGenerated; 13543ca95b02SDimitry Andric 13553ca95b02SDimitry Andric // FIXME: Handle other MethodOptions. 13563ca95b02SDimitry Andric 13573ca95b02SDimitry Andric return MethodOptions::None; 13583ca95b02SDimitry Andric } 13593ca95b02SDimitry Andric 13603ca95b02SDimitry Andric static MethodKind translateMethodKindFlags(const DISubprogram *SP, 13613ca95b02SDimitry Andric bool Introduced) { 13623ca95b02SDimitry Andric switch (SP->getVirtuality()) { 13633ca95b02SDimitry Andric case dwarf::DW_VIRTUALITY_none: 13643ca95b02SDimitry Andric break; 13653ca95b02SDimitry Andric case dwarf::DW_VIRTUALITY_virtual: 13663ca95b02SDimitry Andric return Introduced ? MethodKind::IntroducingVirtual : MethodKind::Virtual; 13673ca95b02SDimitry Andric case dwarf::DW_VIRTUALITY_pure_virtual: 13683ca95b02SDimitry Andric return Introduced ? MethodKind::PureIntroducingVirtual 13693ca95b02SDimitry Andric : MethodKind::PureVirtual; 13703ca95b02SDimitry Andric default: 13713ca95b02SDimitry Andric llvm_unreachable("unhandled virtuality case"); 13723ca95b02SDimitry Andric } 13733ca95b02SDimitry Andric 13743ca95b02SDimitry Andric // FIXME: Get Clang to mark DISubprogram as static and do something with it. 13753ca95b02SDimitry Andric 13763ca95b02SDimitry Andric return MethodKind::Vanilla; 13773ca95b02SDimitry Andric } 13783ca95b02SDimitry Andric 13793ca95b02SDimitry Andric static TypeRecordKind getRecordKind(const DICompositeType *Ty) { 13803ca95b02SDimitry Andric switch (Ty->getTag()) { 13813ca95b02SDimitry Andric case dwarf::DW_TAG_class_type: return TypeRecordKind::Class; 13823ca95b02SDimitry Andric case dwarf::DW_TAG_structure_type: return TypeRecordKind::Struct; 13833ca95b02SDimitry Andric } 13843ca95b02SDimitry Andric llvm_unreachable("unexpected tag"); 13853ca95b02SDimitry Andric } 13863ca95b02SDimitry Andric 13873ca95b02SDimitry Andric /// Return ClassOptions that should be present on both the forward declaration 13883ca95b02SDimitry Andric /// and the defintion of a tag type. 13893ca95b02SDimitry Andric static ClassOptions getCommonClassOptions(const DICompositeType *Ty) { 13903ca95b02SDimitry Andric ClassOptions CO = ClassOptions::None; 13913ca95b02SDimitry Andric 13923ca95b02SDimitry Andric // MSVC always sets this flag, even for local types. Clang doesn't always 13933ca95b02SDimitry Andric // appear to give every type a linkage name, which may be problematic for us. 13943ca95b02SDimitry Andric // FIXME: Investigate the consequences of not following them here. 13953ca95b02SDimitry Andric if (!Ty->getIdentifier().empty()) 13963ca95b02SDimitry Andric CO |= ClassOptions::HasUniqueName; 13973ca95b02SDimitry Andric 13983ca95b02SDimitry Andric // Put the Nested flag on a type if it appears immediately inside a tag type. 13993ca95b02SDimitry Andric // Do not walk the scope chain. Do not attempt to compute ContainsNestedClass 14003ca95b02SDimitry Andric // here. That flag is only set on definitions, and not forward declarations. 14013ca95b02SDimitry Andric const DIScope *ImmediateScope = Ty->getScope().resolve(); 14023ca95b02SDimitry Andric if (ImmediateScope && isa<DICompositeType>(ImmediateScope)) 14033ca95b02SDimitry Andric CO |= ClassOptions::Nested; 14043ca95b02SDimitry Andric 14053ca95b02SDimitry Andric // Put the Scoped flag on function-local types. 14063ca95b02SDimitry Andric for (const DIScope *Scope = ImmediateScope; Scope != nullptr; 14073ca95b02SDimitry Andric Scope = Scope->getScope().resolve()) { 14083ca95b02SDimitry Andric if (isa<DISubprogram>(Scope)) { 14093ca95b02SDimitry Andric CO |= ClassOptions::Scoped; 14103ca95b02SDimitry Andric break; 14113ca95b02SDimitry Andric } 14123ca95b02SDimitry Andric } 14133ca95b02SDimitry Andric 14143ca95b02SDimitry Andric return CO; 14153ca95b02SDimitry Andric } 14163ca95b02SDimitry Andric 14173ca95b02SDimitry Andric TypeIndex CodeViewDebug::lowerTypeEnum(const DICompositeType *Ty) { 14183ca95b02SDimitry Andric ClassOptions CO = getCommonClassOptions(Ty); 14193ca95b02SDimitry Andric TypeIndex FTI; 14203ca95b02SDimitry Andric unsigned EnumeratorCount = 0; 14213ca95b02SDimitry Andric 14223ca95b02SDimitry Andric if (Ty->isForwardDecl()) { 14233ca95b02SDimitry Andric CO |= ClassOptions::ForwardReference; 14243ca95b02SDimitry Andric } else { 14253ca95b02SDimitry Andric FieldListRecordBuilder Fields; 14263ca95b02SDimitry Andric for (const DINode *Element : Ty->getElements()) { 14273ca95b02SDimitry Andric // We assume that the frontend provides all members in source declaration 14283ca95b02SDimitry Andric // order, which is what MSVC does. 14293ca95b02SDimitry Andric if (auto *Enumerator = dyn_cast_or_null<DIEnumerator>(Element)) { 14303ca95b02SDimitry Andric Fields.writeEnumerator(EnumeratorRecord( 14313ca95b02SDimitry Andric MemberAccess::Public, APSInt::getUnsigned(Enumerator->getValue()), 14323ca95b02SDimitry Andric Enumerator->getName())); 14333ca95b02SDimitry Andric EnumeratorCount++; 14343ca95b02SDimitry Andric } 14353ca95b02SDimitry Andric } 14363ca95b02SDimitry Andric FTI = TypeTable.writeFieldList(Fields); 14373ca95b02SDimitry Andric } 14383ca95b02SDimitry Andric 14393ca95b02SDimitry Andric std::string FullName = getFullyQualifiedName(Ty); 14403ca95b02SDimitry Andric 14413ca95b02SDimitry Andric return TypeTable.writeEnum(EnumRecord(EnumeratorCount, CO, FTI, FullName, 14423ca95b02SDimitry Andric Ty->getIdentifier(), 14433ca95b02SDimitry Andric getTypeIndex(Ty->getBaseType()))); 14443ca95b02SDimitry Andric } 14453ca95b02SDimitry Andric 14463ca95b02SDimitry Andric //===----------------------------------------------------------------------===// 14473ca95b02SDimitry Andric // ClassInfo 14483ca95b02SDimitry Andric //===----------------------------------------------------------------------===// 14493ca95b02SDimitry Andric 14503ca95b02SDimitry Andric struct llvm::ClassInfo { 14513ca95b02SDimitry Andric struct MemberInfo { 14523ca95b02SDimitry Andric const DIDerivedType *MemberTypeNode; 14533ca95b02SDimitry Andric uint64_t BaseOffset; 14543ca95b02SDimitry Andric }; 14553ca95b02SDimitry Andric // [MemberInfo] 14563ca95b02SDimitry Andric typedef std::vector<MemberInfo> MemberList; 14573ca95b02SDimitry Andric 14583ca95b02SDimitry Andric typedef TinyPtrVector<const DISubprogram *> MethodsList; 14593ca95b02SDimitry Andric // MethodName -> MethodsList 14603ca95b02SDimitry Andric typedef MapVector<MDString *, MethodsList> MethodsMap; 14613ca95b02SDimitry Andric 14623ca95b02SDimitry Andric /// Base classes. 14633ca95b02SDimitry Andric std::vector<const DIDerivedType *> Inheritance; 14643ca95b02SDimitry Andric 14653ca95b02SDimitry Andric /// Direct members. 14663ca95b02SDimitry Andric MemberList Members; 14673ca95b02SDimitry Andric // Direct overloaded methods gathered by name. 14683ca95b02SDimitry Andric MethodsMap Methods; 14693ca95b02SDimitry Andric 14703ca95b02SDimitry Andric std::vector<const DICompositeType *> NestedClasses; 14713ca95b02SDimitry Andric }; 14723ca95b02SDimitry Andric 14733ca95b02SDimitry Andric void CodeViewDebug::clear() { 14743ca95b02SDimitry Andric assert(CurFn == nullptr); 14753ca95b02SDimitry Andric FileIdMap.clear(); 14763ca95b02SDimitry Andric FnDebugInfo.clear(); 14773ca95b02SDimitry Andric FileToFilepathMap.clear(); 14783ca95b02SDimitry Andric LocalUDTs.clear(); 14793ca95b02SDimitry Andric GlobalUDTs.clear(); 14803ca95b02SDimitry Andric TypeIndices.clear(); 14813ca95b02SDimitry Andric CompleteTypeIndices.clear(); 14823ca95b02SDimitry Andric } 14833ca95b02SDimitry Andric 14843ca95b02SDimitry Andric void CodeViewDebug::collectMemberInfo(ClassInfo &Info, 14853ca95b02SDimitry Andric const DIDerivedType *DDTy) { 14863ca95b02SDimitry Andric if (!DDTy->getName().empty()) { 14873ca95b02SDimitry Andric Info.Members.push_back({DDTy, 0}); 14883ca95b02SDimitry Andric return; 14893ca95b02SDimitry Andric } 14903ca95b02SDimitry Andric // An unnamed member must represent a nested struct or union. Add all the 14913ca95b02SDimitry Andric // indirect fields to the current record. 14923ca95b02SDimitry Andric assert((DDTy->getOffsetInBits() % 8) == 0 && "Unnamed bitfield member!"); 14933ca95b02SDimitry Andric uint64_t Offset = DDTy->getOffsetInBits(); 14943ca95b02SDimitry Andric const DIType *Ty = DDTy->getBaseType().resolve(); 14953ca95b02SDimitry Andric const DICompositeType *DCTy = cast<DICompositeType>(Ty); 14963ca95b02SDimitry Andric ClassInfo NestedInfo = collectClassInfo(DCTy); 14973ca95b02SDimitry Andric for (const ClassInfo::MemberInfo &IndirectField : NestedInfo.Members) 14983ca95b02SDimitry Andric Info.Members.push_back( 14993ca95b02SDimitry Andric {IndirectField.MemberTypeNode, IndirectField.BaseOffset + Offset}); 15003ca95b02SDimitry Andric } 15013ca95b02SDimitry Andric 15023ca95b02SDimitry Andric ClassInfo CodeViewDebug::collectClassInfo(const DICompositeType *Ty) { 15033ca95b02SDimitry Andric ClassInfo Info; 15043ca95b02SDimitry Andric // Add elements to structure type. 15053ca95b02SDimitry Andric DINodeArray Elements = Ty->getElements(); 15063ca95b02SDimitry Andric for (auto *Element : Elements) { 15073ca95b02SDimitry Andric // We assume that the frontend provides all members in source declaration 15083ca95b02SDimitry Andric // order, which is what MSVC does. 15093ca95b02SDimitry Andric if (!Element) 15103ca95b02SDimitry Andric continue; 15113ca95b02SDimitry Andric if (auto *SP = dyn_cast<DISubprogram>(Element)) { 15123ca95b02SDimitry Andric Info.Methods[SP->getRawName()].push_back(SP); 15133ca95b02SDimitry Andric } else if (auto *DDTy = dyn_cast<DIDerivedType>(Element)) { 15143ca95b02SDimitry Andric if (DDTy->getTag() == dwarf::DW_TAG_member) { 15153ca95b02SDimitry Andric collectMemberInfo(Info, DDTy); 15163ca95b02SDimitry Andric } else if (DDTy->getTag() == dwarf::DW_TAG_inheritance) { 15173ca95b02SDimitry Andric Info.Inheritance.push_back(DDTy); 15183ca95b02SDimitry Andric } else if (DDTy->getTag() == dwarf::DW_TAG_friend) { 15193ca95b02SDimitry Andric // Ignore friend members. It appears that MSVC emitted info about 15203ca95b02SDimitry Andric // friends in the past, but modern versions do not. 15213ca95b02SDimitry Andric } 15223ca95b02SDimitry Andric // FIXME: Get Clang to emit function virtual table here and handle it. 15233ca95b02SDimitry Andric } else if (auto *Composite = dyn_cast<DICompositeType>(Element)) { 15243ca95b02SDimitry Andric Info.NestedClasses.push_back(Composite); 15253ca95b02SDimitry Andric } 15263ca95b02SDimitry Andric // Skip other unrecognized kinds of elements. 15273ca95b02SDimitry Andric } 15283ca95b02SDimitry Andric return Info; 15293ca95b02SDimitry Andric } 15303ca95b02SDimitry Andric 15313ca95b02SDimitry Andric TypeIndex CodeViewDebug::lowerTypeClass(const DICompositeType *Ty) { 15323ca95b02SDimitry Andric // First, construct the forward decl. Don't look into Ty to compute the 15333ca95b02SDimitry Andric // forward decl options, since it might not be available in all TUs. 15343ca95b02SDimitry Andric TypeRecordKind Kind = getRecordKind(Ty); 15353ca95b02SDimitry Andric ClassOptions CO = 15363ca95b02SDimitry Andric ClassOptions::ForwardReference | getCommonClassOptions(Ty); 15373ca95b02SDimitry Andric std::string FullName = getFullyQualifiedName(Ty); 15383ca95b02SDimitry Andric TypeIndex FwdDeclTI = TypeTable.writeClass(ClassRecord( 15393ca95b02SDimitry Andric Kind, 0, CO, HfaKind::None, WindowsRTClassKind::None, TypeIndex(), 15403ca95b02SDimitry Andric TypeIndex(), TypeIndex(), 0, FullName, Ty->getIdentifier())); 15413ca95b02SDimitry Andric if (!Ty->isForwardDecl()) 15423ca95b02SDimitry Andric DeferredCompleteTypes.push_back(Ty); 15433ca95b02SDimitry Andric return FwdDeclTI; 15443ca95b02SDimitry Andric } 15453ca95b02SDimitry Andric 15463ca95b02SDimitry Andric TypeIndex CodeViewDebug::lowerCompleteTypeClass(const DICompositeType *Ty) { 15473ca95b02SDimitry Andric // Construct the field list and complete type record. 15483ca95b02SDimitry Andric TypeRecordKind Kind = getRecordKind(Ty); 15493ca95b02SDimitry Andric ClassOptions CO = getCommonClassOptions(Ty); 15503ca95b02SDimitry Andric TypeIndex FieldTI; 15513ca95b02SDimitry Andric TypeIndex VShapeTI; 15523ca95b02SDimitry Andric unsigned FieldCount; 15533ca95b02SDimitry Andric bool ContainsNestedClass; 15543ca95b02SDimitry Andric std::tie(FieldTI, VShapeTI, FieldCount, ContainsNestedClass) = 15553ca95b02SDimitry Andric lowerRecordFieldList(Ty); 15563ca95b02SDimitry Andric 15573ca95b02SDimitry Andric if (ContainsNestedClass) 15583ca95b02SDimitry Andric CO |= ClassOptions::ContainsNestedClass; 15593ca95b02SDimitry Andric 15603ca95b02SDimitry Andric std::string FullName = getFullyQualifiedName(Ty); 15613ca95b02SDimitry Andric 15623ca95b02SDimitry Andric uint64_t SizeInBytes = Ty->getSizeInBits() / 8; 15633ca95b02SDimitry Andric 15643ca95b02SDimitry Andric TypeIndex ClassTI = TypeTable.writeClass(ClassRecord( 15653ca95b02SDimitry Andric Kind, FieldCount, CO, HfaKind::None, WindowsRTClassKind::None, FieldTI, 15663ca95b02SDimitry Andric TypeIndex(), VShapeTI, SizeInBytes, FullName, Ty->getIdentifier())); 15673ca95b02SDimitry Andric 15683ca95b02SDimitry Andric TypeTable.writeUdtSourceLine(UdtSourceLineRecord( 15693ca95b02SDimitry Andric ClassTI, TypeTable.writeStringId(StringIdRecord( 15703ca95b02SDimitry Andric TypeIndex(0x0), getFullFilepath(Ty->getFile()))), 15713ca95b02SDimitry Andric Ty->getLine())); 15723ca95b02SDimitry Andric 15733ca95b02SDimitry Andric addToUDTs(Ty, ClassTI); 15743ca95b02SDimitry Andric 15753ca95b02SDimitry Andric return ClassTI; 15763ca95b02SDimitry Andric } 15773ca95b02SDimitry Andric 15783ca95b02SDimitry Andric TypeIndex CodeViewDebug::lowerTypeUnion(const DICompositeType *Ty) { 15793ca95b02SDimitry Andric ClassOptions CO = 15803ca95b02SDimitry Andric ClassOptions::ForwardReference | getCommonClassOptions(Ty); 15813ca95b02SDimitry Andric std::string FullName = getFullyQualifiedName(Ty); 15823ca95b02SDimitry Andric TypeIndex FwdDeclTI = 15833ca95b02SDimitry Andric TypeTable.writeUnion(UnionRecord(0, CO, HfaKind::None, TypeIndex(), 0, 15843ca95b02SDimitry Andric FullName, Ty->getIdentifier())); 15853ca95b02SDimitry Andric if (!Ty->isForwardDecl()) 15863ca95b02SDimitry Andric DeferredCompleteTypes.push_back(Ty); 15873ca95b02SDimitry Andric return FwdDeclTI; 15883ca95b02SDimitry Andric } 15893ca95b02SDimitry Andric 15903ca95b02SDimitry Andric TypeIndex CodeViewDebug::lowerCompleteTypeUnion(const DICompositeType *Ty) { 15913ca95b02SDimitry Andric ClassOptions CO = ClassOptions::Sealed | getCommonClassOptions(Ty); 15923ca95b02SDimitry Andric TypeIndex FieldTI; 15933ca95b02SDimitry Andric unsigned FieldCount; 15943ca95b02SDimitry Andric bool ContainsNestedClass; 15953ca95b02SDimitry Andric std::tie(FieldTI, std::ignore, FieldCount, ContainsNestedClass) = 15963ca95b02SDimitry Andric lowerRecordFieldList(Ty); 15973ca95b02SDimitry Andric 15983ca95b02SDimitry Andric if (ContainsNestedClass) 15993ca95b02SDimitry Andric CO |= ClassOptions::ContainsNestedClass; 16003ca95b02SDimitry Andric 16013ca95b02SDimitry Andric uint64_t SizeInBytes = Ty->getSizeInBits() / 8; 16023ca95b02SDimitry Andric std::string FullName = getFullyQualifiedName(Ty); 16033ca95b02SDimitry Andric 16043ca95b02SDimitry Andric TypeIndex UnionTI = TypeTable.writeUnion( 16053ca95b02SDimitry Andric UnionRecord(FieldCount, CO, HfaKind::None, FieldTI, SizeInBytes, FullName, 16063ca95b02SDimitry Andric Ty->getIdentifier())); 16073ca95b02SDimitry Andric 16083ca95b02SDimitry Andric TypeTable.writeUdtSourceLine(UdtSourceLineRecord( 16093ca95b02SDimitry Andric UnionTI, TypeTable.writeStringId(StringIdRecord( 16103ca95b02SDimitry Andric TypeIndex(0x0), getFullFilepath(Ty->getFile()))), 16113ca95b02SDimitry Andric Ty->getLine())); 16123ca95b02SDimitry Andric 16133ca95b02SDimitry Andric addToUDTs(Ty, UnionTI); 16143ca95b02SDimitry Andric 16153ca95b02SDimitry Andric return UnionTI; 16163ca95b02SDimitry Andric } 16173ca95b02SDimitry Andric 16183ca95b02SDimitry Andric std::tuple<TypeIndex, TypeIndex, unsigned, bool> 16193ca95b02SDimitry Andric CodeViewDebug::lowerRecordFieldList(const DICompositeType *Ty) { 16203ca95b02SDimitry Andric // Manually count members. MSVC appears to count everything that generates a 16213ca95b02SDimitry Andric // field list record. Each individual overload in a method overload group 16223ca95b02SDimitry Andric // contributes to this count, even though the overload group is a single field 16233ca95b02SDimitry Andric // list record. 16243ca95b02SDimitry Andric unsigned MemberCount = 0; 16253ca95b02SDimitry Andric ClassInfo Info = collectClassInfo(Ty); 16263ca95b02SDimitry Andric FieldListRecordBuilder Fields; 16273ca95b02SDimitry Andric 16283ca95b02SDimitry Andric // Create base classes. 16293ca95b02SDimitry Andric for (const DIDerivedType *I : Info.Inheritance) { 16303ca95b02SDimitry Andric if (I->getFlags() & DINode::FlagVirtual) { 16313ca95b02SDimitry Andric // Virtual base. 16323ca95b02SDimitry Andric // FIXME: Emit VBPtrOffset when the frontend provides it. 16333ca95b02SDimitry Andric unsigned VBPtrOffset = 0; 16343ca95b02SDimitry Andric // FIXME: Despite the accessor name, the offset is really in bytes. 16353ca95b02SDimitry Andric unsigned VBTableIndex = I->getOffsetInBits() / 4; 16363ca95b02SDimitry Andric Fields.writeVirtualBaseClass(VirtualBaseClassRecord( 16373ca95b02SDimitry Andric translateAccessFlags(Ty->getTag(), I->getFlags()), 16383ca95b02SDimitry Andric getTypeIndex(I->getBaseType()), getVBPTypeIndex(), VBPtrOffset, 16393ca95b02SDimitry Andric VBTableIndex)); 16403ca95b02SDimitry Andric } else { 16413ca95b02SDimitry Andric assert(I->getOffsetInBits() % 8 == 0 && 16423ca95b02SDimitry Andric "bases must be on byte boundaries"); 16433ca95b02SDimitry Andric Fields.writeBaseClass(BaseClassRecord( 16443ca95b02SDimitry Andric translateAccessFlags(Ty->getTag(), I->getFlags()), 16453ca95b02SDimitry Andric getTypeIndex(I->getBaseType()), I->getOffsetInBits() / 8)); 16463ca95b02SDimitry Andric } 16473ca95b02SDimitry Andric } 16483ca95b02SDimitry Andric 16493ca95b02SDimitry Andric // Create members. 16503ca95b02SDimitry Andric for (ClassInfo::MemberInfo &MemberInfo : Info.Members) { 16513ca95b02SDimitry Andric const DIDerivedType *Member = MemberInfo.MemberTypeNode; 16523ca95b02SDimitry Andric TypeIndex MemberBaseType = getTypeIndex(Member->getBaseType()); 16533ca95b02SDimitry Andric StringRef MemberName = Member->getName(); 16543ca95b02SDimitry Andric MemberAccess Access = 16553ca95b02SDimitry Andric translateAccessFlags(Ty->getTag(), Member->getFlags()); 16563ca95b02SDimitry Andric 16573ca95b02SDimitry Andric if (Member->isStaticMember()) { 16583ca95b02SDimitry Andric Fields.writeStaticDataMember( 16593ca95b02SDimitry Andric StaticDataMemberRecord(Access, MemberBaseType, MemberName)); 16603ca95b02SDimitry Andric MemberCount++; 16613ca95b02SDimitry Andric continue; 16623ca95b02SDimitry Andric } 16633ca95b02SDimitry Andric 16643ca95b02SDimitry Andric // Data member. 16653ca95b02SDimitry Andric uint64_t MemberOffsetInBits = 16663ca95b02SDimitry Andric Member->getOffsetInBits() + MemberInfo.BaseOffset; 16673ca95b02SDimitry Andric if (Member->isBitField()) { 16683ca95b02SDimitry Andric uint64_t StartBitOffset = MemberOffsetInBits; 16693ca95b02SDimitry Andric if (const auto *CI = 16703ca95b02SDimitry Andric dyn_cast_or_null<ConstantInt>(Member->getStorageOffsetInBits())) { 16713ca95b02SDimitry Andric MemberOffsetInBits = CI->getZExtValue() + MemberInfo.BaseOffset; 16723ca95b02SDimitry Andric } 16733ca95b02SDimitry Andric StartBitOffset -= MemberOffsetInBits; 16743ca95b02SDimitry Andric MemberBaseType = TypeTable.writeBitField(BitFieldRecord( 16753ca95b02SDimitry Andric MemberBaseType, Member->getSizeInBits(), StartBitOffset)); 16763ca95b02SDimitry Andric } 16773ca95b02SDimitry Andric uint64_t MemberOffsetInBytes = MemberOffsetInBits / 8; 16783ca95b02SDimitry Andric Fields.writeDataMember(DataMemberRecord(Access, MemberBaseType, 16793ca95b02SDimitry Andric MemberOffsetInBytes, MemberName)); 16803ca95b02SDimitry Andric MemberCount++; 16813ca95b02SDimitry Andric } 16823ca95b02SDimitry Andric 16833ca95b02SDimitry Andric // Create methods 16843ca95b02SDimitry Andric for (auto &MethodItr : Info.Methods) { 16853ca95b02SDimitry Andric StringRef Name = MethodItr.first->getString(); 16863ca95b02SDimitry Andric 16873ca95b02SDimitry Andric std::vector<OneMethodRecord> Methods; 16883ca95b02SDimitry Andric for (const DISubprogram *SP : MethodItr.second) { 16893ca95b02SDimitry Andric TypeIndex MethodType = getMemberFunctionType(SP, Ty); 16903ca95b02SDimitry Andric bool Introduced = SP->getFlags() & DINode::FlagIntroducedVirtual; 16913ca95b02SDimitry Andric 16923ca95b02SDimitry Andric unsigned VFTableOffset = -1; 16933ca95b02SDimitry Andric if (Introduced) 16943ca95b02SDimitry Andric VFTableOffset = SP->getVirtualIndex() * getPointerSizeInBytes(); 16953ca95b02SDimitry Andric 16963ca95b02SDimitry Andric Methods.push_back( 16973ca95b02SDimitry Andric OneMethodRecord(MethodType, translateMethodKindFlags(SP, Introduced), 16983ca95b02SDimitry Andric translateMethodOptionFlags(SP), 16993ca95b02SDimitry Andric translateAccessFlags(Ty->getTag(), SP->getFlags()), 17003ca95b02SDimitry Andric VFTableOffset, Name)); 17013ca95b02SDimitry Andric MemberCount++; 17023ca95b02SDimitry Andric } 17033ca95b02SDimitry Andric assert(Methods.size() > 0 && "Empty methods map entry"); 17043ca95b02SDimitry Andric if (Methods.size() == 1) 17053ca95b02SDimitry Andric Fields.writeOneMethod(Methods[0]); 17063ca95b02SDimitry Andric else { 17073ca95b02SDimitry Andric TypeIndex MethodList = 17083ca95b02SDimitry Andric TypeTable.writeMethodOverloadList(MethodOverloadListRecord(Methods)); 17093ca95b02SDimitry Andric Fields.writeOverloadedMethod( 17103ca95b02SDimitry Andric OverloadedMethodRecord(Methods.size(), MethodList, Name)); 17113ca95b02SDimitry Andric } 17123ca95b02SDimitry Andric } 17133ca95b02SDimitry Andric 17143ca95b02SDimitry Andric // Create nested classes. 17153ca95b02SDimitry Andric for (const DICompositeType *Nested : Info.NestedClasses) { 17163ca95b02SDimitry Andric NestedTypeRecord R(getTypeIndex(DITypeRef(Nested)), Nested->getName()); 17173ca95b02SDimitry Andric Fields.writeNestedType(R); 17183ca95b02SDimitry Andric MemberCount++; 17193ca95b02SDimitry Andric } 17203ca95b02SDimitry Andric 17213ca95b02SDimitry Andric TypeIndex FieldTI = TypeTable.writeFieldList(Fields); 17223ca95b02SDimitry Andric return std::make_tuple(FieldTI, TypeIndex(), MemberCount, 17233ca95b02SDimitry Andric !Info.NestedClasses.empty()); 17243ca95b02SDimitry Andric } 17253ca95b02SDimitry Andric 17263ca95b02SDimitry Andric TypeIndex CodeViewDebug::getVBPTypeIndex() { 17273ca95b02SDimitry Andric if (!VBPType.getIndex()) { 17283ca95b02SDimitry Andric // Make a 'const int *' type. 17293ca95b02SDimitry Andric ModifierRecord MR(TypeIndex::Int32(), ModifierOptions::Const); 17303ca95b02SDimitry Andric TypeIndex ModifiedTI = TypeTable.writeModifier(MR); 17313ca95b02SDimitry Andric 17323ca95b02SDimitry Andric PointerKind PK = getPointerSizeInBytes() == 8 ? PointerKind::Near64 17333ca95b02SDimitry Andric : PointerKind::Near32; 17343ca95b02SDimitry Andric PointerMode PM = PointerMode::Pointer; 17353ca95b02SDimitry Andric PointerOptions PO = PointerOptions::None; 17363ca95b02SDimitry Andric PointerRecord PR(ModifiedTI, PK, PM, PO, getPointerSizeInBytes()); 17373ca95b02SDimitry Andric 17383ca95b02SDimitry Andric VBPType = TypeTable.writePointer(PR); 17393ca95b02SDimitry Andric } 17403ca95b02SDimitry Andric 17413ca95b02SDimitry Andric return VBPType; 17423ca95b02SDimitry Andric } 17433ca95b02SDimitry Andric 17443ca95b02SDimitry Andric TypeIndex CodeViewDebug::getTypeIndex(DITypeRef TypeRef, DITypeRef ClassTyRef) { 17453ca95b02SDimitry Andric const DIType *Ty = TypeRef.resolve(); 17463ca95b02SDimitry Andric const DIType *ClassTy = ClassTyRef.resolve(); 17473ca95b02SDimitry Andric 17483ca95b02SDimitry Andric // The null DIType is the void type. Don't try to hash it. 17493ca95b02SDimitry Andric if (!Ty) 17503ca95b02SDimitry Andric return TypeIndex::Void(); 17513ca95b02SDimitry Andric 17523ca95b02SDimitry Andric // Check if we've already translated this type. Don't try to do a 17533ca95b02SDimitry Andric // get-or-create style insertion that caches the hash lookup across the 17543ca95b02SDimitry Andric // lowerType call. It will update the TypeIndices map. 17553ca95b02SDimitry Andric auto I = TypeIndices.find({Ty, ClassTy}); 17563ca95b02SDimitry Andric if (I != TypeIndices.end()) 17573ca95b02SDimitry Andric return I->second; 17583ca95b02SDimitry Andric 17593ca95b02SDimitry Andric TypeLoweringScope S(*this); 17603ca95b02SDimitry Andric TypeIndex TI = lowerType(Ty, ClassTy); 17613ca95b02SDimitry Andric return recordTypeIndexForDINode(Ty, TI, ClassTy); 17623ca95b02SDimitry Andric } 17633ca95b02SDimitry Andric 17643ca95b02SDimitry Andric TypeIndex CodeViewDebug::getCompleteTypeIndex(DITypeRef TypeRef) { 17653ca95b02SDimitry Andric const DIType *Ty = TypeRef.resolve(); 17663ca95b02SDimitry Andric 17673ca95b02SDimitry Andric // The null DIType is the void type. Don't try to hash it. 17683ca95b02SDimitry Andric if (!Ty) 17693ca95b02SDimitry Andric return TypeIndex::Void(); 17703ca95b02SDimitry Andric 17713ca95b02SDimitry Andric // If this is a non-record type, the complete type index is the same as the 17723ca95b02SDimitry Andric // normal type index. Just call getTypeIndex. 17733ca95b02SDimitry Andric switch (Ty->getTag()) { 17743ca95b02SDimitry Andric case dwarf::DW_TAG_class_type: 17753ca95b02SDimitry Andric case dwarf::DW_TAG_structure_type: 17763ca95b02SDimitry Andric case dwarf::DW_TAG_union_type: 17773ca95b02SDimitry Andric break; 17783ca95b02SDimitry Andric default: 17793ca95b02SDimitry Andric return getTypeIndex(Ty); 17803ca95b02SDimitry Andric } 17813ca95b02SDimitry Andric 17823ca95b02SDimitry Andric // Check if we've already translated the complete record type. Lowering a 17833ca95b02SDimitry Andric // complete type should never trigger lowering another complete type, so we 17843ca95b02SDimitry Andric // can reuse the hash table lookup result. 17853ca95b02SDimitry Andric const auto *CTy = cast<DICompositeType>(Ty); 17863ca95b02SDimitry Andric auto InsertResult = CompleteTypeIndices.insert({CTy, TypeIndex()}); 17873ca95b02SDimitry Andric if (!InsertResult.second) 17883ca95b02SDimitry Andric return InsertResult.first->second; 17893ca95b02SDimitry Andric 17903ca95b02SDimitry Andric TypeLoweringScope S(*this); 17913ca95b02SDimitry Andric 17923ca95b02SDimitry Andric // Make sure the forward declaration is emitted first. It's unclear if this 17933ca95b02SDimitry Andric // is necessary, but MSVC does it, and we should follow suit until we can show 17943ca95b02SDimitry Andric // otherwise. 17953ca95b02SDimitry Andric TypeIndex FwdDeclTI = getTypeIndex(CTy); 17963ca95b02SDimitry Andric 17973ca95b02SDimitry Andric // Just use the forward decl if we don't have complete type info. This might 17983ca95b02SDimitry Andric // happen if the frontend is using modules and expects the complete definition 17993ca95b02SDimitry Andric // to be emitted elsewhere. 18003ca95b02SDimitry Andric if (CTy->isForwardDecl()) 18013ca95b02SDimitry Andric return FwdDeclTI; 18023ca95b02SDimitry Andric 18033ca95b02SDimitry Andric TypeIndex TI; 18043ca95b02SDimitry Andric switch (CTy->getTag()) { 18053ca95b02SDimitry Andric case dwarf::DW_TAG_class_type: 18063ca95b02SDimitry Andric case dwarf::DW_TAG_structure_type: 18073ca95b02SDimitry Andric TI = lowerCompleteTypeClass(CTy); 18083ca95b02SDimitry Andric break; 18093ca95b02SDimitry Andric case dwarf::DW_TAG_union_type: 18103ca95b02SDimitry Andric TI = lowerCompleteTypeUnion(CTy); 18113ca95b02SDimitry Andric break; 18123ca95b02SDimitry Andric default: 18133ca95b02SDimitry Andric llvm_unreachable("not a record"); 18143ca95b02SDimitry Andric } 18153ca95b02SDimitry Andric 18163ca95b02SDimitry Andric InsertResult.first->second = TI; 18173ca95b02SDimitry Andric return TI; 18183ca95b02SDimitry Andric } 18193ca95b02SDimitry Andric 18203ca95b02SDimitry Andric /// Emit all the deferred complete record types. Try to do this in FIFO order, 18213ca95b02SDimitry Andric /// and do this until fixpoint, as each complete record type typically 18223ca95b02SDimitry Andric /// references 18233ca95b02SDimitry Andric /// many other record types. 18243ca95b02SDimitry Andric void CodeViewDebug::emitDeferredCompleteTypes() { 18253ca95b02SDimitry Andric SmallVector<const DICompositeType *, 4> TypesToEmit; 18263ca95b02SDimitry Andric while (!DeferredCompleteTypes.empty()) { 18273ca95b02SDimitry Andric std::swap(DeferredCompleteTypes, TypesToEmit); 18283ca95b02SDimitry Andric for (const DICompositeType *RecordTy : TypesToEmit) 18293ca95b02SDimitry Andric getCompleteTypeIndex(RecordTy); 18303ca95b02SDimitry Andric TypesToEmit.clear(); 18313ca95b02SDimitry Andric } 18323ca95b02SDimitry Andric } 18333ca95b02SDimitry Andric 18343ca95b02SDimitry Andric void CodeViewDebug::emitLocalVariableList(ArrayRef<LocalVariable> Locals) { 18353ca95b02SDimitry Andric // Get the sorted list of parameters and emit them first. 18363ca95b02SDimitry Andric SmallVector<const LocalVariable *, 6> Params; 18373ca95b02SDimitry Andric for (const LocalVariable &L : Locals) 18383ca95b02SDimitry Andric if (L.DIVar->isParameter()) 18393ca95b02SDimitry Andric Params.push_back(&L); 18403ca95b02SDimitry Andric std::sort(Params.begin(), Params.end(), 18413ca95b02SDimitry Andric [](const LocalVariable *L, const LocalVariable *R) { 18423ca95b02SDimitry Andric return L->DIVar->getArg() < R->DIVar->getArg(); 18433ca95b02SDimitry Andric }); 18443ca95b02SDimitry Andric for (const LocalVariable *L : Params) 18453ca95b02SDimitry Andric emitLocalVariable(*L); 18463ca95b02SDimitry Andric 18473ca95b02SDimitry Andric // Next emit all non-parameters in the order that we found them. 18483ca95b02SDimitry Andric for (const LocalVariable &L : Locals) 18493ca95b02SDimitry Andric if (!L.DIVar->isParameter()) 18503ca95b02SDimitry Andric emitLocalVariable(L); 18513ca95b02SDimitry Andric } 18523ca95b02SDimitry Andric 18533ca95b02SDimitry Andric void CodeViewDebug::emitLocalVariable(const LocalVariable &Var) { 18543ca95b02SDimitry Andric // LocalSym record, see SymbolRecord.h for more info. 18553ca95b02SDimitry Andric MCSymbol *LocalBegin = MMI->getContext().createTempSymbol(), 18563ca95b02SDimitry Andric *LocalEnd = MMI->getContext().createTempSymbol(); 18573ca95b02SDimitry Andric OS.AddComment("Record length"); 18583ca95b02SDimitry Andric OS.emitAbsoluteSymbolDiff(LocalEnd, LocalBegin, 2); 18593ca95b02SDimitry Andric OS.EmitLabel(LocalBegin); 18603ca95b02SDimitry Andric 18613ca95b02SDimitry Andric OS.AddComment("Record kind: S_LOCAL"); 18623ca95b02SDimitry Andric OS.EmitIntValue(unsigned(SymbolKind::S_LOCAL), 2); 18633ca95b02SDimitry Andric 18643ca95b02SDimitry Andric LocalSymFlags Flags = LocalSymFlags::None; 18653ca95b02SDimitry Andric if (Var.DIVar->isParameter()) 18663ca95b02SDimitry Andric Flags |= LocalSymFlags::IsParameter; 18673ca95b02SDimitry Andric if (Var.DefRanges.empty()) 18683ca95b02SDimitry Andric Flags |= LocalSymFlags::IsOptimizedOut; 18693ca95b02SDimitry Andric 18703ca95b02SDimitry Andric OS.AddComment("TypeIndex"); 18713ca95b02SDimitry Andric TypeIndex TI = getCompleteTypeIndex(Var.DIVar->getType()); 18723ca95b02SDimitry Andric OS.EmitIntValue(TI.getIndex(), 4); 18733ca95b02SDimitry Andric OS.AddComment("Flags"); 18743ca95b02SDimitry Andric OS.EmitIntValue(static_cast<uint16_t>(Flags), 2); 18753ca95b02SDimitry Andric // Truncate the name so we won't overflow the record length field. 18763ca95b02SDimitry Andric emitNullTerminatedSymbolName(OS, Var.DIVar->getName()); 18773ca95b02SDimitry Andric OS.EmitLabel(LocalEnd); 18783ca95b02SDimitry Andric 18793ca95b02SDimitry Andric // Calculate the on disk prefix of the appropriate def range record. The 18803ca95b02SDimitry Andric // records and on disk formats are described in SymbolRecords.h. BytePrefix 18813ca95b02SDimitry Andric // should be big enough to hold all forms without memory allocation. 18823ca95b02SDimitry Andric SmallString<20> BytePrefix; 18833ca95b02SDimitry Andric for (const LocalVarDefRange &DefRange : Var.DefRanges) { 18843ca95b02SDimitry Andric BytePrefix.clear(); 18853ca95b02SDimitry Andric // FIXME: Handle bitpieces. 18863ca95b02SDimitry Andric if (DefRange.StructOffset != 0) 18873ca95b02SDimitry Andric continue; 18883ca95b02SDimitry Andric 18893ca95b02SDimitry Andric if (DefRange.InMemory) { 18903ca95b02SDimitry Andric DefRangeRegisterRelSym Sym(DefRange.CVRegister, 0, DefRange.DataOffset, 0, 18913ca95b02SDimitry Andric 0, 0, ArrayRef<LocalVariableAddrGap>()); 18923ca95b02SDimitry Andric ulittle16_t SymKind = ulittle16_t(S_DEFRANGE_REGISTER_REL); 18933ca95b02SDimitry Andric BytePrefix += 18943ca95b02SDimitry Andric StringRef(reinterpret_cast<const char *>(&SymKind), sizeof(SymKind)); 18953ca95b02SDimitry Andric BytePrefix += 18963ca95b02SDimitry Andric StringRef(reinterpret_cast<const char *>(&Sym.Header), 18973ca95b02SDimitry Andric sizeof(Sym.Header) - sizeof(LocalVariableAddrRange)); 18983ca95b02SDimitry Andric } else { 18993ca95b02SDimitry Andric assert(DefRange.DataOffset == 0 && "unexpected offset into register"); 19003ca95b02SDimitry Andric // Unclear what matters here. 19013ca95b02SDimitry Andric DefRangeRegisterSym Sym(DefRange.CVRegister, 0, 0, 0, 0, 19023ca95b02SDimitry Andric ArrayRef<LocalVariableAddrGap>()); 19033ca95b02SDimitry Andric ulittle16_t SymKind = ulittle16_t(S_DEFRANGE_REGISTER); 19043ca95b02SDimitry Andric BytePrefix += 19053ca95b02SDimitry Andric StringRef(reinterpret_cast<const char *>(&SymKind), sizeof(SymKind)); 19063ca95b02SDimitry Andric BytePrefix += 19073ca95b02SDimitry Andric StringRef(reinterpret_cast<const char *>(&Sym.Header), 19083ca95b02SDimitry Andric sizeof(Sym.Header) - sizeof(LocalVariableAddrRange)); 19093ca95b02SDimitry Andric } 19103ca95b02SDimitry Andric OS.EmitCVDefRangeDirective(DefRange.Ranges, BytePrefix); 19113ca95b02SDimitry Andric } 19123ca95b02SDimitry Andric } 19133ca95b02SDimitry Andric 19143ca95b02SDimitry Andric void CodeViewDebug::endFunction(const MachineFunction *MF) { 19153ca95b02SDimitry Andric if (!Asm || !CurFn) // We haven't created any debug info for this function. 19163ca95b02SDimitry Andric return; 19173ca95b02SDimitry Andric 19183ca95b02SDimitry Andric const Function *GV = MF->getFunction(); 19193ca95b02SDimitry Andric assert(FnDebugInfo.count(GV)); 19203ca95b02SDimitry Andric assert(CurFn == &FnDebugInfo[GV]); 19213ca95b02SDimitry Andric 19223ca95b02SDimitry Andric collectVariableInfo(GV->getSubprogram()); 19233ca95b02SDimitry Andric 19243ca95b02SDimitry Andric DebugHandlerBase::endFunction(MF); 19253ca95b02SDimitry Andric 19263ca95b02SDimitry Andric // Don't emit anything if we don't have any line tables. 19273ca95b02SDimitry Andric if (!CurFn->HaveLineInfo) { 19283ca95b02SDimitry Andric FnDebugInfo.erase(GV); 19293ca95b02SDimitry Andric CurFn = nullptr; 19303ca95b02SDimitry Andric return; 19313ca95b02SDimitry Andric } 19323ca95b02SDimitry Andric 19333ca95b02SDimitry Andric CurFn->End = Asm->getFunctionEnd(); 19343ca95b02SDimitry Andric 19353ca95b02SDimitry Andric CurFn = nullptr; 19363ca95b02SDimitry Andric } 19373ca95b02SDimitry Andric 19383ca95b02SDimitry Andric void CodeViewDebug::beginInstruction(const MachineInstr *MI) { 19393ca95b02SDimitry Andric DebugHandlerBase::beginInstruction(MI); 19403ca95b02SDimitry Andric 19413ca95b02SDimitry Andric // Ignore DBG_VALUE locations and function prologue. 19423ca95b02SDimitry Andric if (!Asm || MI->isDebugValue() || MI->getFlag(MachineInstr::FrameSetup)) 19433ca95b02SDimitry Andric return; 19443ca95b02SDimitry Andric DebugLoc DL = MI->getDebugLoc(); 19453ca95b02SDimitry Andric if (DL == PrevInstLoc || !DL) 19463ca95b02SDimitry Andric return; 19473ca95b02SDimitry Andric maybeRecordLocation(DL, Asm->MF); 19483ca95b02SDimitry Andric } 19493ca95b02SDimitry Andric 19503ca95b02SDimitry Andric MCSymbol *CodeViewDebug::beginCVSubsection(ModuleSubstreamKind Kind) { 19513ca95b02SDimitry Andric MCSymbol *BeginLabel = MMI->getContext().createTempSymbol(), 19523ca95b02SDimitry Andric *EndLabel = MMI->getContext().createTempSymbol(); 19533ca95b02SDimitry Andric OS.EmitIntValue(unsigned(Kind), 4); 19543ca95b02SDimitry Andric OS.AddComment("Subsection size"); 19553ca95b02SDimitry Andric OS.emitAbsoluteSymbolDiff(EndLabel, BeginLabel, 4); 19563ca95b02SDimitry Andric OS.EmitLabel(BeginLabel); 19573ca95b02SDimitry Andric return EndLabel; 19583ca95b02SDimitry Andric } 19593ca95b02SDimitry Andric 19603ca95b02SDimitry Andric void CodeViewDebug::endCVSubsection(MCSymbol *EndLabel) { 19613ca95b02SDimitry Andric OS.EmitLabel(EndLabel); 19623ca95b02SDimitry Andric // Every subsection must be aligned to a 4-byte boundary. 19633ca95b02SDimitry Andric OS.EmitValueToAlignment(4); 19643ca95b02SDimitry Andric } 19653ca95b02SDimitry Andric 19663ca95b02SDimitry Andric void CodeViewDebug::emitDebugInfoForUDTs( 19673ca95b02SDimitry Andric ArrayRef<std::pair<std::string, TypeIndex>> UDTs) { 19683ca95b02SDimitry Andric for (const std::pair<std::string, codeview::TypeIndex> &UDT : UDTs) { 19693ca95b02SDimitry Andric MCSymbol *UDTRecordBegin = MMI->getContext().createTempSymbol(), 19703ca95b02SDimitry Andric *UDTRecordEnd = MMI->getContext().createTempSymbol(); 19713ca95b02SDimitry Andric OS.AddComment("Record length"); 19723ca95b02SDimitry Andric OS.emitAbsoluteSymbolDiff(UDTRecordEnd, UDTRecordBegin, 2); 19733ca95b02SDimitry Andric OS.EmitLabel(UDTRecordBegin); 19743ca95b02SDimitry Andric 19753ca95b02SDimitry Andric OS.AddComment("Record kind: S_UDT"); 19763ca95b02SDimitry Andric OS.EmitIntValue(unsigned(SymbolKind::S_UDT), 2); 19773ca95b02SDimitry Andric 19783ca95b02SDimitry Andric OS.AddComment("Type"); 19793ca95b02SDimitry Andric OS.EmitIntValue(UDT.second.getIndex(), 4); 19803ca95b02SDimitry Andric 19813ca95b02SDimitry Andric emitNullTerminatedSymbolName(OS, UDT.first); 19823ca95b02SDimitry Andric OS.EmitLabel(UDTRecordEnd); 19833ca95b02SDimitry Andric } 19843ca95b02SDimitry Andric } 19853ca95b02SDimitry Andric 19863ca95b02SDimitry Andric void CodeViewDebug::emitDebugInfoForGlobals() { 19873ca95b02SDimitry Andric NamedMDNode *CUs = MMI->getModule()->getNamedMetadata("llvm.dbg.cu"); 19883ca95b02SDimitry Andric for (const MDNode *Node : CUs->operands()) { 19893ca95b02SDimitry Andric const auto *CU = cast<DICompileUnit>(Node); 19903ca95b02SDimitry Andric 19913ca95b02SDimitry Andric // First, emit all globals that are not in a comdat in a single symbol 19923ca95b02SDimitry Andric // substream. MSVC doesn't like it if the substream is empty, so only open 19933ca95b02SDimitry Andric // it if we have at least one global to emit. 19943ca95b02SDimitry Andric switchToDebugSectionForSymbol(nullptr); 19953ca95b02SDimitry Andric MCSymbol *EndLabel = nullptr; 19963ca95b02SDimitry Andric for (const DIGlobalVariable *G : CU->getGlobalVariables()) { 19973ca95b02SDimitry Andric if (const auto *GV = dyn_cast_or_null<GlobalVariable>(G->getVariable())) { 19983ca95b02SDimitry Andric if (!GV->hasComdat() && !GV->isDeclarationForLinker()) { 19993ca95b02SDimitry Andric if (!EndLabel) { 20003ca95b02SDimitry Andric OS.AddComment("Symbol subsection for globals"); 20013ca95b02SDimitry Andric EndLabel = beginCVSubsection(ModuleSubstreamKind::Symbols); 20023ca95b02SDimitry Andric } 20033ca95b02SDimitry Andric emitDebugInfoForGlobal(G, Asm->getSymbol(GV)); 20043ca95b02SDimitry Andric } 20053ca95b02SDimitry Andric } 20063ca95b02SDimitry Andric } 20073ca95b02SDimitry Andric if (EndLabel) 20083ca95b02SDimitry Andric endCVSubsection(EndLabel); 20093ca95b02SDimitry Andric 20103ca95b02SDimitry Andric // Second, emit each global that is in a comdat into its own .debug$S 20113ca95b02SDimitry Andric // section along with its own symbol substream. 20123ca95b02SDimitry Andric for (const DIGlobalVariable *G : CU->getGlobalVariables()) { 20133ca95b02SDimitry Andric if (const auto *GV = dyn_cast_or_null<GlobalVariable>(G->getVariable())) { 20143ca95b02SDimitry Andric if (GV->hasComdat()) { 20153ca95b02SDimitry Andric MCSymbol *GVSym = Asm->getSymbol(GV); 20163ca95b02SDimitry Andric OS.AddComment("Symbol subsection for " + 20173ca95b02SDimitry Andric Twine(GlobalValue::getRealLinkageName(GV->getName()))); 20183ca95b02SDimitry Andric switchToDebugSectionForSymbol(GVSym); 20193ca95b02SDimitry Andric EndLabel = beginCVSubsection(ModuleSubstreamKind::Symbols); 20203ca95b02SDimitry Andric emitDebugInfoForGlobal(G, GVSym); 20213ca95b02SDimitry Andric endCVSubsection(EndLabel); 20223ca95b02SDimitry Andric } 20233ca95b02SDimitry Andric } 20243ca95b02SDimitry Andric } 20253ca95b02SDimitry Andric } 20263ca95b02SDimitry Andric } 20273ca95b02SDimitry Andric 20283ca95b02SDimitry Andric void CodeViewDebug::emitDebugInfoForRetainedTypes() { 20293ca95b02SDimitry Andric NamedMDNode *CUs = MMI->getModule()->getNamedMetadata("llvm.dbg.cu"); 20303ca95b02SDimitry Andric for (const MDNode *Node : CUs->operands()) { 20313ca95b02SDimitry Andric for (auto *Ty : cast<DICompileUnit>(Node)->getRetainedTypes()) { 20323ca95b02SDimitry Andric if (DIType *RT = dyn_cast<DIType>(Ty)) { 20333ca95b02SDimitry Andric getTypeIndex(RT); 20343ca95b02SDimitry Andric // FIXME: Add to global/local DTU list. 20353ca95b02SDimitry Andric } 20363ca95b02SDimitry Andric } 20373ca95b02SDimitry Andric } 20383ca95b02SDimitry Andric } 20393ca95b02SDimitry Andric 20403ca95b02SDimitry Andric void CodeViewDebug::emitDebugInfoForGlobal(const DIGlobalVariable *DIGV, 20413ca95b02SDimitry Andric MCSymbol *GVSym) { 20423ca95b02SDimitry Andric // DataSym record, see SymbolRecord.h for more info. 20433ca95b02SDimitry Andric // FIXME: Thread local data, etc 20443ca95b02SDimitry Andric MCSymbol *DataBegin = MMI->getContext().createTempSymbol(), 20453ca95b02SDimitry Andric *DataEnd = MMI->getContext().createTempSymbol(); 20463ca95b02SDimitry Andric OS.AddComment("Record length"); 20473ca95b02SDimitry Andric OS.emitAbsoluteSymbolDiff(DataEnd, DataBegin, 2); 20483ca95b02SDimitry Andric OS.EmitLabel(DataBegin); 20493ca95b02SDimitry Andric const auto *GV = cast<GlobalVariable>(DIGV->getVariable()); 20503ca95b02SDimitry Andric if (DIGV->isLocalToUnit()) { 20513ca95b02SDimitry Andric if (GV->isThreadLocal()) { 20523ca95b02SDimitry Andric OS.AddComment("Record kind: S_LTHREAD32"); 20533ca95b02SDimitry Andric OS.EmitIntValue(unsigned(SymbolKind::S_LTHREAD32), 2); 20543ca95b02SDimitry Andric } else { 20553ca95b02SDimitry Andric OS.AddComment("Record kind: S_LDATA32"); 20563ca95b02SDimitry Andric OS.EmitIntValue(unsigned(SymbolKind::S_LDATA32), 2); 20573ca95b02SDimitry Andric } 20583ca95b02SDimitry Andric } else { 20593ca95b02SDimitry Andric if (GV->isThreadLocal()) { 20603ca95b02SDimitry Andric OS.AddComment("Record kind: S_GTHREAD32"); 20613ca95b02SDimitry Andric OS.EmitIntValue(unsigned(SymbolKind::S_GTHREAD32), 2); 20623ca95b02SDimitry Andric } else { 20633ca95b02SDimitry Andric OS.AddComment("Record kind: S_GDATA32"); 20643ca95b02SDimitry Andric OS.EmitIntValue(unsigned(SymbolKind::S_GDATA32), 2); 20653ca95b02SDimitry Andric } 20663ca95b02SDimitry Andric } 20673ca95b02SDimitry Andric OS.AddComment("Type"); 20683ca95b02SDimitry Andric OS.EmitIntValue(getCompleteTypeIndex(DIGV->getType()).getIndex(), 4); 20693ca95b02SDimitry Andric OS.AddComment("DataOffset"); 20703ca95b02SDimitry Andric OS.EmitCOFFSecRel32(GVSym); 20713ca95b02SDimitry Andric OS.AddComment("Segment"); 20723ca95b02SDimitry Andric OS.EmitCOFFSectionIndex(GVSym); 20733ca95b02SDimitry Andric OS.AddComment("Name"); 20743ca95b02SDimitry Andric emitNullTerminatedSymbolName(OS, DIGV->getName()); 20753ca95b02SDimitry Andric OS.EmitLabel(DataEnd); 20763ca95b02SDimitry Andric } 2077