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