xref: /src/contrib/llvm-project/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp (revision 5f757f3ff9144b609b3c433dfd370cc6bdc191ad)
17ab83427SDimitry Andric //===- llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp ----------------------===//
201095a5dSDimitry Andric //
3e6d15924SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4e6d15924SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
5e6d15924SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
601095a5dSDimitry Andric //
701095a5dSDimitry Andric //===----------------------------------------------------------------------===//
801095a5dSDimitry Andric //
901095a5dSDimitry Andric // This file contains support for writing Microsoft CodeView debug info.
1001095a5dSDimitry Andric //
1101095a5dSDimitry Andric //===----------------------------------------------------------------------===//
1201095a5dSDimitry Andric 
1301095a5dSDimitry Andric #include "CodeViewDebug.h"
147ab83427SDimitry Andric #include "llvm/ADT/APSInt.h"
15044eb2f6SDimitry Andric #include "llvm/ADT/STLExtras.h"
16b1c73532SDimitry Andric #include "llvm/ADT/SmallBitVector.h"
177ab83427SDimitry Andric #include "llvm/ADT/SmallString.h"
187ab83427SDimitry Andric #include "llvm/ADT/StringRef.h"
1901095a5dSDimitry Andric #include "llvm/ADT/TinyPtrVector.h"
207ab83427SDimitry Andric #include "llvm/ADT/Twine.h"
217ab83427SDimitry Andric #include "llvm/BinaryFormat/COFF.h"
227ab83427SDimitry Andric #include "llvm/BinaryFormat/Dwarf.h"
237ab83427SDimitry Andric #include "llvm/CodeGen/AsmPrinter.h"
247ab83427SDimitry Andric #include "llvm/CodeGen/LexicalScopes.h"
25d8e91e46SDimitry Andric #include "llvm/CodeGen/MachineFrameInfo.h"
267ab83427SDimitry Andric #include "llvm/CodeGen/MachineFunction.h"
277ab83427SDimitry Andric #include "llvm/CodeGen/MachineInstr.h"
287ab83427SDimitry Andric #include "llvm/CodeGen/MachineModuleInfo.h"
29044eb2f6SDimitry Andric #include "llvm/CodeGen/TargetFrameLowering.h"
30b1c73532SDimitry Andric #include "llvm/CodeGen/TargetLowering.h"
31044eb2f6SDimitry Andric #include "llvm/CodeGen/TargetRegisterInfo.h"
32044eb2f6SDimitry Andric #include "llvm/CodeGen/TargetSubtargetInfo.h"
337ab83427SDimitry Andric #include "llvm/Config/llvm-config.h"
3401095a5dSDimitry Andric #include "llvm/DebugInfo/CodeView/CVTypeVisitor.h"
35e6d15924SDimitry Andric #include "llvm/DebugInfo/CodeView/CodeViewRecordIO.h"
36044eb2f6SDimitry Andric #include "llvm/DebugInfo/CodeView/ContinuationRecordBuilder.h"
37ee2f195dSDimitry Andric #include "llvm/DebugInfo/CodeView/DebugInlineeLinesSubsection.h"
38d8e91e46SDimitry Andric #include "llvm/DebugInfo/CodeView/EnumTables.h"
3901095a5dSDimitry Andric #include "llvm/DebugInfo/CodeView/Line.h"
4001095a5dSDimitry Andric #include "llvm/DebugInfo/CodeView/SymbolRecord.h"
4101095a5dSDimitry Andric #include "llvm/DebugInfo/CodeView/TypeRecord.h"
42b5630dbaSDimitry Andric #include "llvm/DebugInfo/CodeView/TypeTableCollection.h"
43e6d15924SDimitry Andric #include "llvm/DebugInfo/CodeView/TypeVisitorCallbackPipeline.h"
4401095a5dSDimitry Andric #include "llvm/IR/Constants.h"
457ab83427SDimitry Andric #include "llvm/IR/DataLayout.h"
467ab83427SDimitry Andric #include "llvm/IR/DebugInfoMetadata.h"
477ab83427SDimitry Andric #include "llvm/IR/Function.h"
487ab83427SDimitry Andric #include "llvm/IR/GlobalValue.h"
497ab83427SDimitry Andric #include "llvm/IR/GlobalVariable.h"
507ab83427SDimitry Andric #include "llvm/IR/Metadata.h"
517ab83427SDimitry Andric #include "llvm/IR/Module.h"
52b915e9e0SDimitry Andric #include "llvm/MC/MCAsmInfo.h"
537ab83427SDimitry Andric #include "llvm/MC/MCContext.h"
5401095a5dSDimitry Andric #include "llvm/MC/MCSectionCOFF.h"
557ab83427SDimitry Andric #include "llvm/MC/MCStreamer.h"
5601095a5dSDimitry Andric #include "llvm/MC/MCSymbol.h"
57e6d15924SDimitry Andric #include "llvm/Support/BinaryStreamWriter.h"
587ab83427SDimitry Andric #include "llvm/Support/Casting.h"
597ab83427SDimitry Andric #include "llvm/Support/Error.h"
607ab83427SDimitry Andric #include "llvm/Support/ErrorHandling.h"
61044eb2f6SDimitry Andric #include "llvm/Support/FormatVariadic.h"
62d8e91e46SDimitry Andric #include "llvm/Support/Path.h"
636f8fc217SDimitry Andric #include "llvm/Support/Program.h"
647ab83427SDimitry Andric #include "llvm/Support/SMLoc.h"
65044eb2f6SDimitry Andric #include "llvm/Support/ScopedPrinter.h"
66eb11fae6SDimitry Andric #include "llvm/Target/TargetLoweringObjectFile.h"
677ab83427SDimitry Andric #include "llvm/Target/TargetMachine.h"
687fa27ce4SDimitry Andric #include "llvm/TargetParser/Triple.h"
697ab83427SDimitry Andric #include <algorithm>
707ab83427SDimitry Andric #include <cassert>
717ab83427SDimitry Andric #include <cctype>
727ab83427SDimitry Andric #include <cstddef>
737ab83427SDimitry Andric #include <iterator>
747ab83427SDimitry Andric #include <limits>
7501095a5dSDimitry Andric 
7601095a5dSDimitry Andric using namespace llvm;
7701095a5dSDimitry Andric using namespace llvm::codeview;
7801095a5dSDimitry Andric 
79e6d15924SDimitry Andric namespace {
80e6d15924SDimitry Andric class CVMCAdapter : public CodeViewRecordStreamer {
81e6d15924SDimitry Andric public:
CVMCAdapter(MCStreamer & OS,TypeCollection & TypeTable)821d5ae102SDimitry Andric   CVMCAdapter(MCStreamer &OS, TypeCollection &TypeTable)
831d5ae102SDimitry Andric       : OS(&OS), TypeTable(TypeTable) {}
84e6d15924SDimitry Andric 
emitBytes(StringRef Data)85cfca06d7SDimitry Andric   void emitBytes(StringRef Data) override { OS->emitBytes(Data); }
86e6d15924SDimitry Andric 
emitIntValue(uint64_t Value,unsigned Size)87cfca06d7SDimitry Andric   void emitIntValue(uint64_t Value, unsigned Size) override {
88cfca06d7SDimitry Andric     OS->emitIntValueInHex(Value, Size);
89e6d15924SDimitry Andric   }
90e6d15924SDimitry Andric 
emitBinaryData(StringRef Data)91cfca06d7SDimitry Andric   void emitBinaryData(StringRef Data) override { OS->emitBinaryData(Data); }
92e6d15924SDimitry Andric 
AddComment(const Twine & T)93cfca06d7SDimitry Andric   void AddComment(const Twine &T) override { OS->AddComment(T); }
94e6d15924SDimitry Andric 
AddRawComment(const Twine & T)95cfca06d7SDimitry Andric   void AddRawComment(const Twine &T) override { OS->emitRawComment(T); }
961d5ae102SDimitry Andric 
isVerboseAsm()97cfca06d7SDimitry Andric   bool isVerboseAsm() override { return OS->isVerboseAsm(); }
981d5ae102SDimitry Andric 
getTypeName(TypeIndex TI)99cfca06d7SDimitry Andric   std::string getTypeName(TypeIndex TI) override {
1001d5ae102SDimitry Andric     std::string TypeName;
1011d5ae102SDimitry Andric     if (!TI.isNoneType()) {
1021d5ae102SDimitry Andric       if (TI.isSimple())
103cfca06d7SDimitry Andric         TypeName = std::string(TypeIndex::simpleTypeName(TI));
1041d5ae102SDimitry Andric       else
105cfca06d7SDimitry Andric         TypeName = std::string(TypeTable.getTypeName(TI));
1061d5ae102SDimitry Andric     }
1071d5ae102SDimitry Andric     return TypeName;
1081d5ae102SDimitry Andric   }
1091d5ae102SDimitry Andric 
110e6d15924SDimitry Andric private:
111e6d15924SDimitry Andric   MCStreamer *OS = nullptr;
1121d5ae102SDimitry Andric   TypeCollection &TypeTable;
113e6d15924SDimitry Andric };
114e6d15924SDimitry Andric } // namespace
115e6d15924SDimitry Andric 
mapArchToCVCPUType(Triple::ArchType Type)116d8e91e46SDimitry Andric static CPUType mapArchToCVCPUType(Triple::ArchType Type) {
117d8e91e46SDimitry Andric   switch (Type) {
118d8e91e46SDimitry Andric   case Triple::ArchType::x86:
119d8e91e46SDimitry Andric     return CPUType::Pentium3;
120d8e91e46SDimitry Andric   case Triple::ArchType::x86_64:
121d8e91e46SDimitry Andric     return CPUType::X64;
122d8e91e46SDimitry Andric   case Triple::ArchType::thumb:
123b60736ecSDimitry Andric     // LLVM currently doesn't support Windows CE and so thumb
124b60736ecSDimitry Andric     // here is indiscriminately mapped to ARMNT specifically.
125b60736ecSDimitry Andric     return CPUType::ARMNT;
126d8e91e46SDimitry Andric   case Triple::ArchType::aarch64:
127d8e91e46SDimitry Andric     return CPUType::ARM64;
128d8e91e46SDimitry Andric   default:
129d8e91e46SDimitry Andric     report_fatal_error("target architecture doesn't map to a CodeView CPUType");
130d8e91e46SDimitry Andric   }
131d8e91e46SDimitry Andric }
132044eb2f6SDimitry Andric 
CodeViewDebug(AsmPrinter * AP)13301095a5dSDimitry Andric CodeViewDebug::CodeViewDebug(AsmPrinter *AP)
134b60736ecSDimitry Andric     : DebugHandlerBase(AP), OS(*Asm->OutStreamer), TypeTable(Allocator) {}
13501095a5dSDimitry Andric 
getFullFilepath(const DIFile * File)13601095a5dSDimitry Andric StringRef CodeViewDebug::getFullFilepath(const DIFile *File) {
13701095a5dSDimitry Andric   std::string &Filepath = FileToFilepathMap[File];
13801095a5dSDimitry Andric   if (!Filepath.empty())
13901095a5dSDimitry Andric     return Filepath;
14001095a5dSDimitry Andric 
14101095a5dSDimitry Andric   StringRef Dir = File->getDirectory(), Filename = File->getFilename();
14201095a5dSDimitry Andric 
143eb11fae6SDimitry Andric   // If this is a Unix-style path, just use it as is. Don't try to canonicalize
144eb11fae6SDimitry Andric   // it textually because one of the path components could be a symlink.
145b1c73532SDimitry Andric   if (Dir.starts_with("/") || Filename.starts_with("/")) {
146d8e91e46SDimitry Andric     if (llvm::sys::path::is_absolute(Filename, llvm::sys::path::Style::posix))
147d8e91e46SDimitry Andric       return Filename;
148cfca06d7SDimitry Andric     Filepath = std::string(Dir);
149eb11fae6SDimitry Andric     if (Dir.back() != '/')
150eb11fae6SDimitry Andric       Filepath += '/';
151eb11fae6SDimitry Andric     Filepath += Filename;
152eb11fae6SDimitry Andric     return Filepath;
153eb11fae6SDimitry Andric   }
154eb11fae6SDimitry Andric 
15501095a5dSDimitry Andric   // Clang emits directory and relative filename info into the IR, but CodeView
15601095a5dSDimitry Andric   // operates on full paths.  We could change Clang to emit full paths too, but
15701095a5dSDimitry Andric   // that would increase the IR size and probably not needed for other users.
15801095a5dSDimitry Andric   // For now, just concatenate and canonicalize the path here.
15901095a5dSDimitry Andric   if (Filename.find(':') == 1)
160cfca06d7SDimitry Andric     Filepath = std::string(Filename);
16101095a5dSDimitry Andric   else
16201095a5dSDimitry Andric     Filepath = (Dir + "\\" + Filename).str();
16301095a5dSDimitry Andric 
16401095a5dSDimitry Andric   // Canonicalize the path.  We have to do it textually because we may no longer
16501095a5dSDimitry Andric   // have access the file in the filesystem.
16601095a5dSDimitry Andric   // First, replace all slashes with backslashes.
16701095a5dSDimitry Andric   std::replace(Filepath.begin(), Filepath.end(), '/', '\\');
16801095a5dSDimitry Andric 
16901095a5dSDimitry Andric   // Remove all "\.\" with "\".
17001095a5dSDimitry Andric   size_t Cursor = 0;
17101095a5dSDimitry Andric   while ((Cursor = Filepath.find("\\.\\", Cursor)) != std::string::npos)
17201095a5dSDimitry Andric     Filepath.erase(Cursor, 2);
17301095a5dSDimitry Andric 
17401095a5dSDimitry Andric   // Replace all "\XXX\..\" with "\".  Don't try too hard though as the original
17501095a5dSDimitry Andric   // path should be well-formatted, e.g. start with a drive letter, etc.
17601095a5dSDimitry Andric   Cursor = 0;
17701095a5dSDimitry Andric   while ((Cursor = Filepath.find("\\..\\", Cursor)) != std::string::npos) {
17801095a5dSDimitry Andric     // Something's wrong if the path starts with "\..\", abort.
17901095a5dSDimitry Andric     if (Cursor == 0)
18001095a5dSDimitry Andric       break;
18101095a5dSDimitry Andric 
18201095a5dSDimitry Andric     size_t PrevSlash = Filepath.rfind('\\', Cursor - 1);
18301095a5dSDimitry Andric     if (PrevSlash == std::string::npos)
18401095a5dSDimitry Andric       // Something's wrong, abort.
18501095a5dSDimitry Andric       break;
18601095a5dSDimitry Andric 
18701095a5dSDimitry Andric     Filepath.erase(PrevSlash, Cursor + 3 - PrevSlash);
18801095a5dSDimitry Andric     // The next ".." might be following the one we've just erased.
18901095a5dSDimitry Andric     Cursor = PrevSlash;
19001095a5dSDimitry Andric   }
19101095a5dSDimitry Andric 
19201095a5dSDimitry Andric   // Remove all duplicate backslashes.
19301095a5dSDimitry Andric   Cursor = 0;
19401095a5dSDimitry Andric   while ((Cursor = Filepath.find("\\\\", Cursor)) != std::string::npos)
19501095a5dSDimitry Andric     Filepath.erase(Cursor, 1);
19601095a5dSDimitry Andric 
19701095a5dSDimitry Andric   return Filepath;
19801095a5dSDimitry Andric }
19901095a5dSDimitry Andric 
maybeRecordFile(const DIFile * F)20001095a5dSDimitry Andric unsigned CodeViewDebug::maybeRecordFile(const DIFile *F) {
201044eb2f6SDimitry Andric   StringRef FullPath = getFullFilepath(F);
20201095a5dSDimitry Andric   unsigned NextId = FileIdMap.size() + 1;
203044eb2f6SDimitry Andric   auto Insertion = FileIdMap.insert(std::make_pair(FullPath, NextId));
20401095a5dSDimitry Andric   if (Insertion.second) {
20501095a5dSDimitry Andric     // We have to compute the full filepath and emit a .cv_file directive.
206eb11fae6SDimitry Andric     ArrayRef<uint8_t> ChecksumAsBytes;
207eb11fae6SDimitry Andric     FileChecksumKind CSKind = FileChecksumKind::None;
208eb11fae6SDimitry Andric     if (F->getChecksum()) {
209eb11fae6SDimitry Andric       std::string Checksum = fromHex(F->getChecksum()->Value);
210044eb2f6SDimitry Andric       void *CKMem = OS.getContext().allocate(Checksum.size(), 1);
211044eb2f6SDimitry Andric       memcpy(CKMem, Checksum.data(), Checksum.size());
212eb11fae6SDimitry Andric       ChecksumAsBytes = ArrayRef<uint8_t>(
213eb11fae6SDimitry Andric           reinterpret_cast<const uint8_t *>(CKMem), Checksum.size());
214eb11fae6SDimitry Andric       switch (F->getChecksum()->Kind) {
215cfca06d7SDimitry Andric       case DIFile::CSK_MD5:
216cfca06d7SDimitry Andric         CSKind = FileChecksumKind::MD5;
217cfca06d7SDimitry Andric         break;
218cfca06d7SDimitry Andric       case DIFile::CSK_SHA1:
219cfca06d7SDimitry Andric         CSKind = FileChecksumKind::SHA1;
220cfca06d7SDimitry Andric         break;
221cfca06d7SDimitry Andric       case DIFile::CSK_SHA256:
222cfca06d7SDimitry Andric         CSKind = FileChecksumKind::SHA256;
223cfca06d7SDimitry Andric         break;
224eb11fae6SDimitry Andric       }
225eb11fae6SDimitry Andric     }
226145449b1SDimitry Andric     bool Success = OS.emitCVFileDirective(NextId, FullPath, ChecksumAsBytes,
227eb11fae6SDimitry Andric                                           static_cast<unsigned>(CSKind));
228b915e9e0SDimitry Andric     (void)Success;
229b915e9e0SDimitry Andric     assert(Success && ".cv_file directive failed");
23001095a5dSDimitry Andric   }
23101095a5dSDimitry Andric   return Insertion.first->second;
23201095a5dSDimitry Andric }
23301095a5dSDimitry Andric 
23401095a5dSDimitry Andric CodeViewDebug::InlineSite &
getInlineSite(const DILocation * InlinedAt,const DISubprogram * Inlinee)23501095a5dSDimitry Andric CodeViewDebug::getInlineSite(const DILocation *InlinedAt,
23601095a5dSDimitry Andric                              const DISubprogram *Inlinee) {
23701095a5dSDimitry Andric   auto SiteInsertion = CurFn->InlineSites.insert({InlinedAt, InlineSite()});
23801095a5dSDimitry Andric   InlineSite *Site = &SiteInsertion.first->second;
23901095a5dSDimitry Andric   if (SiteInsertion.second) {
240b915e9e0SDimitry Andric     unsigned ParentFuncId = CurFn->FuncId;
241b915e9e0SDimitry Andric     if (const DILocation *OuterIA = InlinedAt->getInlinedAt())
242b915e9e0SDimitry Andric       ParentFuncId =
243b915e9e0SDimitry Andric           getInlineSite(OuterIA, InlinedAt->getScope()->getSubprogram())
244b915e9e0SDimitry Andric               .SiteFuncId;
245b915e9e0SDimitry Andric 
24601095a5dSDimitry Andric     Site->SiteFuncId = NextFuncId++;
247145449b1SDimitry Andric     OS.emitCVInlineSiteIdDirective(
248b915e9e0SDimitry Andric         Site->SiteFuncId, ParentFuncId, maybeRecordFile(InlinedAt->getFile()),
249b915e9e0SDimitry Andric         InlinedAt->getLine(), InlinedAt->getColumn(), SMLoc());
25001095a5dSDimitry Andric     Site->Inlinee = Inlinee;
25101095a5dSDimitry Andric     InlinedSubprograms.insert(Inlinee);
252b1c73532SDimitry Andric     auto InlineeIdx = getFuncIdForSubprogram(Inlinee);
253b1c73532SDimitry Andric 
254b1c73532SDimitry Andric     if (InlinedAt->getInlinedAt() == nullptr)
255b1c73532SDimitry Andric       CurFn->Inlinees.insert(InlineeIdx);
25601095a5dSDimitry Andric   }
25701095a5dSDimitry Andric   return *Site;
25801095a5dSDimitry Andric }
25901095a5dSDimitry Andric 
getPrettyScopeName(const DIScope * Scope)26001095a5dSDimitry Andric static StringRef getPrettyScopeName(const DIScope *Scope) {
26101095a5dSDimitry Andric   StringRef ScopeName = Scope->getName();
26201095a5dSDimitry Andric   if (!ScopeName.empty())
26301095a5dSDimitry Andric     return ScopeName;
26401095a5dSDimitry Andric 
26501095a5dSDimitry Andric   switch (Scope->getTag()) {
26601095a5dSDimitry Andric   case dwarf::DW_TAG_enumeration_type:
26701095a5dSDimitry Andric   case dwarf::DW_TAG_class_type:
26801095a5dSDimitry Andric   case dwarf::DW_TAG_structure_type:
26901095a5dSDimitry Andric   case dwarf::DW_TAG_union_type:
27001095a5dSDimitry Andric     return "<unnamed-tag>";
27101095a5dSDimitry Andric   case dwarf::DW_TAG_namespace:
27201095a5dSDimitry Andric     return "`anonymous namespace'";
273344a3780SDimitry Andric   default:
27401095a5dSDimitry Andric     return StringRef();
27501095a5dSDimitry Andric   }
276344a3780SDimitry Andric }
27701095a5dSDimitry Andric 
collectParentScopeNames(const DIScope * Scope,SmallVectorImpl<StringRef> & QualifiedNameComponents)278cfca06d7SDimitry Andric const DISubprogram *CodeViewDebug::collectParentScopeNames(
27901095a5dSDimitry Andric     const DIScope *Scope, SmallVectorImpl<StringRef> &QualifiedNameComponents) {
28001095a5dSDimitry Andric   const DISubprogram *ClosestSubprogram = nullptr;
28101095a5dSDimitry Andric   while (Scope != nullptr) {
28201095a5dSDimitry Andric     if (ClosestSubprogram == nullptr)
28301095a5dSDimitry Andric       ClosestSubprogram = dyn_cast<DISubprogram>(Scope);
284cfca06d7SDimitry Andric 
285cfca06d7SDimitry Andric     // If a type appears in a scope chain, make sure it gets emitted. The
286cfca06d7SDimitry Andric     // frontend will be responsible for deciding if this should be a forward
287cfca06d7SDimitry Andric     // declaration or a complete type.
288cfca06d7SDimitry Andric     if (const auto *Ty = dyn_cast<DICompositeType>(Scope))
289cfca06d7SDimitry Andric       DeferredCompleteTypes.push_back(Ty);
290cfca06d7SDimitry Andric 
29101095a5dSDimitry Andric     StringRef ScopeName = getPrettyScopeName(Scope);
29201095a5dSDimitry Andric     if (!ScopeName.empty())
29301095a5dSDimitry Andric       QualifiedNameComponents.push_back(ScopeName);
294e6d15924SDimitry Andric     Scope = Scope->getScope();
29501095a5dSDimitry Andric   }
29601095a5dSDimitry Andric   return ClosestSubprogram;
29701095a5dSDimitry Andric }
29801095a5dSDimitry Andric 
formatNestedName(ArrayRef<StringRef> QualifiedNameComponents,StringRef TypeName)299cfca06d7SDimitry Andric static std::string formatNestedName(ArrayRef<StringRef> QualifiedNameComponents,
30001095a5dSDimitry Andric                                     StringRef TypeName) {
30101095a5dSDimitry Andric   std::string FullyQualifiedName;
3027ab83427SDimitry Andric   for (StringRef QualifiedNameComponent :
3037ab83427SDimitry Andric        llvm::reverse(QualifiedNameComponents)) {
304cfca06d7SDimitry Andric     FullyQualifiedName.append(std::string(QualifiedNameComponent));
30501095a5dSDimitry Andric     FullyQualifiedName.append("::");
30601095a5dSDimitry Andric   }
307cfca06d7SDimitry Andric   FullyQualifiedName.append(std::string(TypeName));
30801095a5dSDimitry Andric   return FullyQualifiedName;
30901095a5dSDimitry Andric }
31001095a5dSDimitry Andric 
31101095a5dSDimitry Andric struct CodeViewDebug::TypeLoweringScope {
TypeLoweringScopeCodeViewDebug::TypeLoweringScope31201095a5dSDimitry Andric   TypeLoweringScope(CodeViewDebug &CVD) : CVD(CVD) { ++CVD.TypeEmissionLevel; }
~TypeLoweringScopeCodeViewDebug::TypeLoweringScope31301095a5dSDimitry Andric   ~TypeLoweringScope() {
31401095a5dSDimitry Andric     // Don't decrement TypeEmissionLevel until after emitting deferred types, so
31501095a5dSDimitry Andric     // inner TypeLoweringScopes don't attempt to emit deferred types.
31601095a5dSDimitry Andric     if (CVD.TypeEmissionLevel == 1)
31701095a5dSDimitry Andric       CVD.emitDeferredCompleteTypes();
31801095a5dSDimitry Andric     --CVD.TypeEmissionLevel;
31901095a5dSDimitry Andric   }
32001095a5dSDimitry Andric   CodeViewDebug &CVD;
32101095a5dSDimitry Andric };
32201095a5dSDimitry Andric 
getFullyQualifiedName(const DIScope * Scope,StringRef Name)323cfca06d7SDimitry Andric std::string CodeViewDebug::getFullyQualifiedName(const DIScope *Scope,
324cfca06d7SDimitry Andric                                                  StringRef Name) {
325cfca06d7SDimitry Andric   // Ensure types in the scope chain are emitted as soon as possible.
326cfca06d7SDimitry Andric   // This can create otherwise a situation where S_UDTs are emitted while
327cfca06d7SDimitry Andric   // looping in emitDebugInfoForUDTs.
328cfca06d7SDimitry Andric   TypeLoweringScope S(*this);
329cfca06d7SDimitry Andric   SmallVector<StringRef, 5> QualifiedNameComponents;
330cfca06d7SDimitry Andric   collectParentScopeNames(Scope, QualifiedNameComponents);
331cfca06d7SDimitry Andric   return formatNestedName(QualifiedNameComponents, Name);
332cfca06d7SDimitry Andric }
333cfca06d7SDimitry Andric 
getFullyQualifiedName(const DIScope * Ty)334cfca06d7SDimitry Andric std::string CodeViewDebug::getFullyQualifiedName(const DIScope *Ty) {
335e6d15924SDimitry Andric   const DIScope *Scope = Ty->getScope();
33601095a5dSDimitry Andric   return getFullyQualifiedName(Scope, getPrettyScopeName(Ty));
33701095a5dSDimitry Andric }
33801095a5dSDimitry Andric 
getScopeIndex(const DIScope * Scope)33901095a5dSDimitry Andric TypeIndex CodeViewDebug::getScopeIndex(const DIScope *Scope) {
34001095a5dSDimitry Andric   // No scope means global scope and that uses the zero index.
341c0981da4SDimitry Andric   //
342c0981da4SDimitry Andric   // We also use zero index when the scope is a DISubprogram
343c0981da4SDimitry Andric   // to suppress the emission of LF_STRING_ID for the function,
344c0981da4SDimitry Andric   // which can trigger a link-time error with the linker in
345c0981da4SDimitry Andric   // VS2019 version 16.11.2 or newer.
346c0981da4SDimitry Andric   // Note, however, skipping the debug info emission for the DISubprogram
347c0981da4SDimitry Andric   // is a temporary fix. The root issue here is that we need to figure out
348c0981da4SDimitry Andric   // the proper way to encode a function nested in another function
349c0981da4SDimitry Andric   // (as introduced by the Fortran 'contains' keyword) in CodeView.
350c0981da4SDimitry Andric   if (!Scope || isa<DIFile>(Scope) || isa<DISubprogram>(Scope))
35101095a5dSDimitry Andric     return TypeIndex();
35201095a5dSDimitry Andric 
35301095a5dSDimitry Andric   assert(!isa<DIType>(Scope) && "shouldn't make a namespace scope for a type");
35401095a5dSDimitry Andric 
35501095a5dSDimitry Andric   // Check if we've already translated this scope.
35601095a5dSDimitry Andric   auto I = TypeIndices.find({Scope, nullptr});
35701095a5dSDimitry Andric   if (I != TypeIndices.end())
35801095a5dSDimitry Andric     return I->second;
35901095a5dSDimitry Andric 
36001095a5dSDimitry Andric   // Build the fully qualified name of the scope.
36101095a5dSDimitry Andric   std::string ScopeName = getFullyQualifiedName(Scope);
362b915e9e0SDimitry Andric   StringIdRecord SID(TypeIndex(), ScopeName);
363044eb2f6SDimitry Andric   auto TI = TypeTable.writeLeafType(SID);
36401095a5dSDimitry Andric   return recordTypeIndexForDINode(Scope, TI);
36501095a5dSDimitry Andric }
36601095a5dSDimitry Andric 
removeTemplateArgs(StringRef Name)367344a3780SDimitry Andric static StringRef removeTemplateArgs(StringRef Name) {
368344a3780SDimitry Andric   // Remove template args from the display name. Assume that the template args
369344a3780SDimitry Andric   // are the last thing in the name.
370344a3780SDimitry Andric   if (Name.empty() || Name.back() != '>')
371344a3780SDimitry Andric     return Name;
372344a3780SDimitry Andric 
373344a3780SDimitry Andric   int OpenBrackets = 0;
374344a3780SDimitry Andric   for (int i = Name.size() - 1; i >= 0; --i) {
375344a3780SDimitry Andric     if (Name[i] == '>')
376344a3780SDimitry Andric       ++OpenBrackets;
377344a3780SDimitry Andric     else if (Name[i] == '<') {
378344a3780SDimitry Andric       --OpenBrackets;
379344a3780SDimitry Andric       if (OpenBrackets == 0)
380344a3780SDimitry Andric         return Name.substr(0, i);
381344a3780SDimitry Andric     }
382344a3780SDimitry Andric   }
383344a3780SDimitry Andric   return Name;
384344a3780SDimitry Andric }
385344a3780SDimitry Andric 
getFuncIdForSubprogram(const DISubprogram * SP)38601095a5dSDimitry Andric TypeIndex CodeViewDebug::getFuncIdForSubprogram(const DISubprogram *SP) {
387a7fe922bSDimitry Andric   assert(SP);
38801095a5dSDimitry Andric 
38901095a5dSDimitry Andric   // Check if we've already translated this subprogram.
39001095a5dSDimitry Andric   auto I = TypeIndices.find({SP, nullptr});
39101095a5dSDimitry Andric   if (I != TypeIndices.end())
39201095a5dSDimitry Andric     return I->second;
39301095a5dSDimitry Andric 
39401095a5dSDimitry Andric   // The display name includes function template arguments. Drop them to match
395344a3780SDimitry Andric   // MSVC. We need to have the template arguments in the DISubprogram name
396344a3780SDimitry Andric   // because they are used in other symbol records, such as S_GPROC32_IDs.
397344a3780SDimitry Andric   StringRef DisplayName = removeTemplateArgs(SP->getName());
39801095a5dSDimitry Andric 
399e6d15924SDimitry Andric   const DIScope *Scope = SP->getScope();
40001095a5dSDimitry Andric   TypeIndex TI;
40101095a5dSDimitry Andric   if (const auto *Class = dyn_cast_or_null<DICompositeType>(Scope)) {
40201095a5dSDimitry Andric     // If the scope is a DICompositeType, then this must be a method. Member
40301095a5dSDimitry Andric     // function types take some special handling, and require access to the
40401095a5dSDimitry Andric     // subprogram.
40501095a5dSDimitry Andric     TypeIndex ClassType = getTypeIndex(Class);
40601095a5dSDimitry Andric     MemberFuncIdRecord MFuncId(ClassType, getMemberFunctionType(SP, Class),
40701095a5dSDimitry Andric                                DisplayName);
408044eb2f6SDimitry Andric     TI = TypeTable.writeLeafType(MFuncId);
40901095a5dSDimitry Andric   } else {
41001095a5dSDimitry Andric     // Otherwise, this must be a free function.
41101095a5dSDimitry Andric     TypeIndex ParentScope = getScopeIndex(Scope);
41201095a5dSDimitry Andric     FuncIdRecord FuncId(ParentScope, getTypeIndex(SP->getType()), DisplayName);
413044eb2f6SDimitry Andric     TI = TypeTable.writeLeafType(FuncId);
41401095a5dSDimitry Andric   }
41501095a5dSDimitry Andric 
41601095a5dSDimitry Andric   return recordTypeIndexForDINode(SP, TI);
41701095a5dSDimitry Andric }
41801095a5dSDimitry Andric 
isNonTrivial(const DICompositeType * DCTy)419e6d15924SDimitry Andric static bool isNonTrivial(const DICompositeType *DCTy) {
420e6d15924SDimitry Andric   return ((DCTy->getFlags() & DINode::FlagNonTrivial) == DINode::FlagNonTrivial);
421d8e91e46SDimitry Andric }
422d8e91e46SDimitry Andric 
423d8e91e46SDimitry Andric static FunctionOptions
getFunctionOptions(const DISubroutineType * Ty,const DICompositeType * ClassTy=nullptr,StringRef SPName=StringRef (""))424d8e91e46SDimitry Andric getFunctionOptions(const DISubroutineType *Ty,
425d8e91e46SDimitry Andric                    const DICompositeType *ClassTy = nullptr,
426d8e91e46SDimitry Andric                    StringRef SPName = StringRef("")) {
427d8e91e46SDimitry Andric   FunctionOptions FO = FunctionOptions::None;
428d8e91e46SDimitry Andric   const DIType *ReturnTy = nullptr;
429d8e91e46SDimitry Andric   if (auto TypeArray = Ty->getTypeArray()) {
430d8e91e46SDimitry Andric     if (TypeArray.size())
431e6d15924SDimitry Andric       ReturnTy = TypeArray[0];
432d8e91e46SDimitry Andric   }
433d8e91e46SDimitry Andric 
434cfca06d7SDimitry Andric   // Add CxxReturnUdt option to functions that return nontrivial record types
435cfca06d7SDimitry Andric   // or methods that return record types.
436cfca06d7SDimitry Andric   if (auto *ReturnDCTy = dyn_cast_or_null<DICompositeType>(ReturnTy))
437cfca06d7SDimitry Andric     if (isNonTrivial(ReturnDCTy) || ClassTy)
438d8e91e46SDimitry Andric       FO |= FunctionOptions::CxxReturnUdt;
439d8e91e46SDimitry Andric 
440d8e91e46SDimitry Andric   // DISubroutineType is unnamed. Use DISubprogram's i.e. SPName in comparison.
441e6d15924SDimitry Andric   if (ClassTy && isNonTrivial(ClassTy) && SPName == ClassTy->getName()) {
442d8e91e46SDimitry Andric     FO |= FunctionOptions::Constructor;
443d8e91e46SDimitry Andric 
444d8e91e46SDimitry Andric   // TODO: put the FunctionOptions::ConstructorWithVirtualBases flag.
445d8e91e46SDimitry Andric 
446d8e91e46SDimitry Andric   }
447d8e91e46SDimitry Andric   return FO;
448d8e91e46SDimitry Andric }
449d8e91e46SDimitry Andric 
getMemberFunctionType(const DISubprogram * SP,const DICompositeType * Class)45001095a5dSDimitry Andric TypeIndex CodeViewDebug::getMemberFunctionType(const DISubprogram *SP,
45101095a5dSDimitry Andric                                                const DICompositeType *Class) {
45201095a5dSDimitry Andric   // Always use the method declaration as the key for the function type. The
45301095a5dSDimitry Andric   // method declaration contains the this adjustment.
45401095a5dSDimitry Andric   if (SP->getDeclaration())
45501095a5dSDimitry Andric     SP = SP->getDeclaration();
45601095a5dSDimitry Andric   assert(!SP->getDeclaration() && "should use declaration as key");
45701095a5dSDimitry Andric 
45801095a5dSDimitry Andric   // Key the MemberFunctionRecord into the map as {SP, Class}. It won't collide
45901095a5dSDimitry Andric   // with the MemberFuncIdRecord, which is keyed in as {SP, nullptr}.
46001095a5dSDimitry Andric   auto I = TypeIndices.find({SP, Class});
46101095a5dSDimitry Andric   if (I != TypeIndices.end())
46201095a5dSDimitry Andric     return I->second;
46301095a5dSDimitry Andric 
46401095a5dSDimitry Andric   // Make sure complete type info for the class is emitted *after* the member
46501095a5dSDimitry Andric   // function type, as the complete class type is likely to reference this
46601095a5dSDimitry Andric   // member function type.
46701095a5dSDimitry Andric   TypeLoweringScope S(*this);
468044eb2f6SDimitry Andric   const bool IsStaticMethod = (SP->getFlags() & DINode::FlagStaticMember) != 0;
469d8e91e46SDimitry Andric 
470d8e91e46SDimitry Andric   FunctionOptions FO = getFunctionOptions(SP->getType(), Class, SP->getName());
471044eb2f6SDimitry Andric   TypeIndex TI = lowerTypeMemberFunction(
472d8e91e46SDimitry Andric       SP->getType(), Class, SP->getThisAdjustment(), IsStaticMethod, FO);
47301095a5dSDimitry Andric   return recordTypeIndexForDINode(SP, TI, Class);
47401095a5dSDimitry Andric }
47501095a5dSDimitry Andric 
recordTypeIndexForDINode(const DINode * Node,TypeIndex TI,const DIType * ClassTy)47601095a5dSDimitry Andric TypeIndex CodeViewDebug::recordTypeIndexForDINode(const DINode *Node,
47701095a5dSDimitry Andric                                                   TypeIndex TI,
47801095a5dSDimitry Andric                                                   const DIType *ClassTy) {
47901095a5dSDimitry Andric   auto InsertResult = TypeIndices.insert({{Node, ClassTy}, TI});
48001095a5dSDimitry Andric   (void)InsertResult;
48101095a5dSDimitry Andric   assert(InsertResult.second && "DINode was already assigned a type index");
48201095a5dSDimitry Andric   return TI;
48301095a5dSDimitry Andric }
48401095a5dSDimitry Andric 
getPointerSizeInBytes()48501095a5dSDimitry Andric unsigned CodeViewDebug::getPointerSizeInBytes() {
48601095a5dSDimitry Andric   return MMI->getModule()->getDataLayout().getPointerSizeInBits() / 8;
48701095a5dSDimitry Andric }
48801095a5dSDimitry Andric 
recordLocalVariable(LocalVariable && Var,const LexicalScope * LS)48901095a5dSDimitry Andric void CodeViewDebug::recordLocalVariable(LocalVariable &&Var,
490eb11fae6SDimitry Andric                                         const LexicalScope *LS) {
491eb11fae6SDimitry Andric   if (const DILocation *InlinedAt = LS->getInlinedAt()) {
49201095a5dSDimitry Andric     // This variable was inlined. Associate it with the InlineSite.
49301095a5dSDimitry Andric     const DISubprogram *Inlinee = Var.DIVar->getScope()->getSubprogram();
49401095a5dSDimitry Andric     InlineSite &Site = getInlineSite(InlinedAt, Inlinee);
4957fa27ce4SDimitry Andric     Site.InlinedLocals.emplace_back(std::move(Var));
49601095a5dSDimitry Andric   } else {
497eb11fae6SDimitry Andric     // This variable goes into the corresponding lexical scope.
4987fa27ce4SDimitry Andric     ScopeVariables[LS].emplace_back(std::move(Var));
49901095a5dSDimitry Andric   }
50001095a5dSDimitry Andric }
50101095a5dSDimitry Andric 
addLocIfNotPresent(SmallVectorImpl<const DILocation * > & Locs,const DILocation * Loc)50201095a5dSDimitry Andric static void addLocIfNotPresent(SmallVectorImpl<const DILocation *> &Locs,
50301095a5dSDimitry Andric                                const DILocation *Loc) {
504b60736ecSDimitry Andric   if (!llvm::is_contained(Locs, Loc))
50501095a5dSDimitry Andric     Locs.push_back(Loc);
50601095a5dSDimitry Andric }
50701095a5dSDimitry Andric 
maybeRecordLocation(const DebugLoc & DL,const MachineFunction * MF)50801095a5dSDimitry Andric void CodeViewDebug::maybeRecordLocation(const DebugLoc &DL,
50901095a5dSDimitry Andric                                         const MachineFunction *MF) {
51001095a5dSDimitry Andric   // Skip this instruction if it has the same location as the previous one.
5119df3605dSDimitry Andric   if (!DL || DL == PrevInstLoc)
51201095a5dSDimitry Andric     return;
51301095a5dSDimitry Andric 
514145449b1SDimitry Andric   const DIScope *Scope = DL->getScope();
51501095a5dSDimitry Andric   if (!Scope)
51601095a5dSDimitry Andric     return;
51701095a5dSDimitry Andric 
51801095a5dSDimitry Andric   // Skip this line if it is longer than the maximum we can record.
51901095a5dSDimitry Andric   LineInfo LI(DL.getLine(), DL.getLine(), /*IsStatement=*/true);
52001095a5dSDimitry Andric   if (LI.getStartLine() != DL.getLine() || LI.isAlwaysStepInto() ||
52101095a5dSDimitry Andric       LI.isNeverStepInto())
52201095a5dSDimitry Andric     return;
52301095a5dSDimitry Andric 
52401095a5dSDimitry Andric   ColumnInfo CI(DL.getCol(), /*EndColumn=*/0);
52501095a5dSDimitry Andric   if (CI.getStartColumn() != DL.getCol())
52601095a5dSDimitry Andric     return;
52701095a5dSDimitry Andric 
52801095a5dSDimitry Andric   if (!CurFn->HaveLineInfo)
52901095a5dSDimitry Andric     CurFn->HaveLineInfo = true;
53001095a5dSDimitry Andric   unsigned FileId = 0;
5319df3605dSDimitry Andric   if (PrevInstLoc.get() && PrevInstLoc->getFile() == DL->getFile())
53201095a5dSDimitry Andric     FileId = CurFn->LastFileId;
53301095a5dSDimitry Andric   else
53401095a5dSDimitry Andric     FileId = CurFn->LastFileId = maybeRecordFile(DL->getFile());
5359df3605dSDimitry Andric   PrevInstLoc = DL;
53601095a5dSDimitry Andric 
53701095a5dSDimitry Andric   unsigned FuncId = CurFn->FuncId;
53801095a5dSDimitry Andric   if (const DILocation *SiteLoc = DL->getInlinedAt()) {
53901095a5dSDimitry Andric     const DILocation *Loc = DL.get();
54001095a5dSDimitry Andric 
54101095a5dSDimitry Andric     // If this location was actually inlined from somewhere else, give it the ID
54201095a5dSDimitry Andric     // of the inline call site.
54301095a5dSDimitry Andric     FuncId =
54401095a5dSDimitry Andric         getInlineSite(SiteLoc, Loc->getScope()->getSubprogram()).SiteFuncId;
54501095a5dSDimitry Andric 
54601095a5dSDimitry Andric     // Ensure we have links in the tree of inline call sites.
54701095a5dSDimitry Andric     bool FirstLoc = true;
54801095a5dSDimitry Andric     while ((SiteLoc = Loc->getInlinedAt())) {
54901095a5dSDimitry Andric       InlineSite &Site =
55001095a5dSDimitry Andric           getInlineSite(SiteLoc, Loc->getScope()->getSubprogram());
55101095a5dSDimitry Andric       if (!FirstLoc)
55201095a5dSDimitry Andric         addLocIfNotPresent(Site.ChildSites, Loc);
55301095a5dSDimitry Andric       FirstLoc = false;
55401095a5dSDimitry Andric       Loc = SiteLoc;
55501095a5dSDimitry Andric     }
55601095a5dSDimitry Andric     addLocIfNotPresent(CurFn->ChildSites, Loc);
55701095a5dSDimitry Andric   }
55801095a5dSDimitry Andric 
559cfca06d7SDimitry Andric   OS.emitCVLocDirective(FuncId, FileId, DL.getLine(), DL.getCol(),
560b915e9e0SDimitry Andric                         /*PrologueEnd=*/false, /*IsStmt=*/false,
561b915e9e0SDimitry Andric                         DL->getFilename(), SMLoc());
56201095a5dSDimitry Andric }
56301095a5dSDimitry Andric 
emitCodeViewMagicVersion()56401095a5dSDimitry Andric void CodeViewDebug::emitCodeViewMagicVersion() {
565e3b55780SDimitry Andric   OS.emitValueToAlignment(Align(4));
56601095a5dSDimitry Andric   OS.AddComment("Debug section magic");
567cfca06d7SDimitry Andric   OS.emitInt32(COFF::DEBUG_SECTION_MAGIC);
56801095a5dSDimitry Andric }
56901095a5dSDimitry Andric 
MapDWLangToCVLang(unsigned DWLang)570c0981da4SDimitry Andric static SourceLanguage MapDWLangToCVLang(unsigned DWLang) {
571c0981da4SDimitry Andric   switch (DWLang) {
572c0981da4SDimitry Andric   case dwarf::DW_LANG_C:
573c0981da4SDimitry Andric   case dwarf::DW_LANG_C89:
574c0981da4SDimitry Andric   case dwarf::DW_LANG_C99:
575c0981da4SDimitry Andric   case dwarf::DW_LANG_C11:
576c0981da4SDimitry Andric     return SourceLanguage::C;
577c0981da4SDimitry Andric   case dwarf::DW_LANG_C_plus_plus:
578c0981da4SDimitry Andric   case dwarf::DW_LANG_C_plus_plus_03:
579c0981da4SDimitry Andric   case dwarf::DW_LANG_C_plus_plus_11:
580c0981da4SDimitry Andric   case dwarf::DW_LANG_C_plus_plus_14:
581c0981da4SDimitry Andric     return SourceLanguage::Cpp;
582c0981da4SDimitry Andric   case dwarf::DW_LANG_Fortran77:
583c0981da4SDimitry Andric   case dwarf::DW_LANG_Fortran90:
584c0981da4SDimitry Andric   case dwarf::DW_LANG_Fortran95:
585c0981da4SDimitry Andric   case dwarf::DW_LANG_Fortran03:
586c0981da4SDimitry Andric   case dwarf::DW_LANG_Fortran08:
587c0981da4SDimitry Andric     return SourceLanguage::Fortran;
588c0981da4SDimitry Andric   case dwarf::DW_LANG_Pascal83:
589c0981da4SDimitry Andric     return SourceLanguage::Pascal;
590c0981da4SDimitry Andric   case dwarf::DW_LANG_Cobol74:
591c0981da4SDimitry Andric   case dwarf::DW_LANG_Cobol85:
592c0981da4SDimitry Andric     return SourceLanguage::Cobol;
593c0981da4SDimitry Andric   case dwarf::DW_LANG_Java:
594c0981da4SDimitry Andric     return SourceLanguage::Java;
595c0981da4SDimitry Andric   case dwarf::DW_LANG_D:
596c0981da4SDimitry Andric     return SourceLanguage::D;
597c0981da4SDimitry Andric   case dwarf::DW_LANG_Swift:
598c0981da4SDimitry Andric     return SourceLanguage::Swift;
5996f8fc217SDimitry Andric   case dwarf::DW_LANG_Rust:
6006f8fc217SDimitry Andric     return SourceLanguage::Rust;
6017fa27ce4SDimitry Andric   case dwarf::DW_LANG_ObjC:
6027fa27ce4SDimitry Andric     return SourceLanguage::ObjC;
6037fa27ce4SDimitry Andric   case dwarf::DW_LANG_ObjC_plus_plus:
6047fa27ce4SDimitry Andric     return SourceLanguage::ObjCpp;
605c0981da4SDimitry Andric   default:
606c0981da4SDimitry Andric     // There's no CodeView representation for this language, and CV doesn't
607c0981da4SDimitry Andric     // have an "unknown" option for the language field, so we'll use MASM,
608c0981da4SDimitry Andric     // as it's very low level.
609c0981da4SDimitry Andric     return SourceLanguage::Masm;
610c0981da4SDimitry Andric   }
611c0981da4SDimitry Andric }
612c0981da4SDimitry Andric 
beginModule(Module * M)613b60736ecSDimitry Andric void CodeViewDebug::beginModule(Module *M) {
614b60736ecSDimitry Andric   // If module doesn't have named metadata anchors or COFF debug section
615b60736ecSDimitry Andric   // is not available, skip any debug info related stuff.
616145449b1SDimitry Andric   if (!MMI->hasDebugInfo() ||
617145449b1SDimitry Andric       !Asm->getObjFileLowering().getCOFFDebugSymbolsSection()) {
618b60736ecSDimitry Andric     Asm = nullptr;
619b60736ecSDimitry Andric     return;
620b60736ecSDimitry Andric   }
621b60736ecSDimitry Andric 
622b60736ecSDimitry Andric   TheCPU = mapArchToCVCPUType(Triple(M->getTargetTriple()).getArch());
623b60736ecSDimitry Andric 
624c0981da4SDimitry Andric   // Get the current source language.
625145449b1SDimitry Andric   const MDNode *Node = *M->debug_compile_units_begin();
626c0981da4SDimitry Andric   const auto *CU = cast<DICompileUnit>(Node);
627c0981da4SDimitry Andric 
628c0981da4SDimitry Andric   CurrentSourceLanguage = MapDWLangToCVLang(CU->getSourceLanguage());
629c0981da4SDimitry Andric 
630b60736ecSDimitry Andric   collectGlobalVariableInfo();
631b60736ecSDimitry Andric 
632b60736ecSDimitry Andric   // Check if we should emit type record hashes.
633b60736ecSDimitry Andric   ConstantInt *GH =
634b60736ecSDimitry Andric       mdconst::extract_or_null<ConstantInt>(M->getModuleFlag("CodeViewGHash"));
635b60736ecSDimitry Andric   EmitDebugGlobalHashes = GH && !GH->isZero();
636b60736ecSDimitry Andric }
637b60736ecSDimitry Andric 
endModule()63801095a5dSDimitry Andric void CodeViewDebug::endModule() {
63901095a5dSDimitry Andric   if (!Asm || !MMI->hasDebugInfo())
64001095a5dSDimitry Andric     return;
64101095a5dSDimitry Andric 
64201095a5dSDimitry Andric   // The COFF .debug$S section consists of several subsections, each starting
64301095a5dSDimitry Andric   // with a 4-byte control code (e.g. 0xF1, 0xF2, etc) and then a 4-byte length
64401095a5dSDimitry Andric   // of the payload followed by the payload itself.  The subsections are 4-byte
64501095a5dSDimitry Andric   // aligned.
64601095a5dSDimitry Andric 
64701095a5dSDimitry Andric   // Use the generic .debug$S section, and make a subsection for all the inlined
64801095a5dSDimitry Andric   // subprograms.
64901095a5dSDimitry Andric   switchToDebugSectionForSymbol(nullptr);
650b915e9e0SDimitry Andric 
651ee2f195dSDimitry Andric   MCSymbol *CompilerInfo = beginCVSubsection(DebugSubsectionKind::Symbols);
65277fc4c14SDimitry Andric   emitObjName();
653b915e9e0SDimitry Andric   emitCompilerInformation();
654b915e9e0SDimitry Andric   endCVSubsection(CompilerInfo);
655b915e9e0SDimitry Andric 
65601095a5dSDimitry Andric   emitInlineeLinesSubsection();
65701095a5dSDimitry Andric 
65801095a5dSDimitry Andric   // Emit per-function debug information.
65901095a5dSDimitry Andric   for (auto &P : FnDebugInfo)
66001095a5dSDimitry Andric     if (!P.first->isDeclarationForLinker())
661eb11fae6SDimitry Andric       emitDebugInfoForFunction(P.first, *P.second);
66201095a5dSDimitry Andric 
663b60736ecSDimitry Andric   // Get types used by globals without emitting anything.
664b60736ecSDimitry Andric   // This is meant to collect all static const data members so they can be
665b60736ecSDimitry Andric   // emitted as globals.
666b60736ecSDimitry Andric   collectDebugInfoForGlobals();
66701095a5dSDimitry Andric 
66801095a5dSDimitry Andric   // Emit retained types.
66901095a5dSDimitry Andric   emitDebugInfoForRetainedTypes();
67001095a5dSDimitry Andric 
671b60736ecSDimitry Andric   // Emit global variable debug information.
672b60736ecSDimitry Andric   setCurrentSubprogram(nullptr);
673b60736ecSDimitry Andric   emitDebugInfoForGlobals();
674b60736ecSDimitry Andric 
67501095a5dSDimitry Andric   // Switch back to the generic .debug$S section after potentially processing
67601095a5dSDimitry Andric   // comdat symbol sections.
67701095a5dSDimitry Andric   switchToDebugSectionForSymbol(nullptr);
67801095a5dSDimitry Andric 
67901095a5dSDimitry Andric   // Emit UDT records for any types used by global variables.
68001095a5dSDimitry Andric   if (!GlobalUDTs.empty()) {
681ee2f195dSDimitry Andric     MCSymbol *SymbolsEnd = beginCVSubsection(DebugSubsectionKind::Symbols);
68201095a5dSDimitry Andric     emitDebugInfoForUDTs(GlobalUDTs);
68301095a5dSDimitry Andric     endCVSubsection(SymbolsEnd);
68401095a5dSDimitry Andric   }
68501095a5dSDimitry Andric 
68601095a5dSDimitry Andric   // This subsection holds a file index to offset in string table table.
68701095a5dSDimitry Andric   OS.AddComment("File index to string table offset subsection");
688cfca06d7SDimitry Andric   OS.emitCVFileChecksumsDirective();
68901095a5dSDimitry Andric 
69001095a5dSDimitry Andric   // This subsection holds the string table.
69101095a5dSDimitry Andric   OS.AddComment("String table");
692cfca06d7SDimitry Andric   OS.emitCVStringTableDirective();
69301095a5dSDimitry Andric 
694d8e91e46SDimitry Andric   // Emit S_BUILDINFO, which points to LF_BUILDINFO. Put this in its own symbol
695d8e91e46SDimitry Andric   // subsection in the generic .debug$S section at the end. There is no
696d8e91e46SDimitry Andric   // particular reason for this ordering other than to match MSVC.
697d8e91e46SDimitry Andric   emitBuildInfo();
698d8e91e46SDimitry Andric 
699044eb2f6SDimitry Andric   // Emit type information and hashes last, so that any types we translate while
700044eb2f6SDimitry Andric   // emitting function info are included.
70101095a5dSDimitry Andric   emitTypeInformation();
70201095a5dSDimitry Andric 
703044eb2f6SDimitry Andric   if (EmitDebugGlobalHashes)
704044eb2f6SDimitry Andric     emitTypeGlobalHashes();
705044eb2f6SDimitry Andric 
70601095a5dSDimitry Andric   clear();
70701095a5dSDimitry Andric }
70801095a5dSDimitry Andric 
709e6d15924SDimitry Andric static void
emitNullTerminatedSymbolName(MCStreamer & OS,StringRef S,unsigned MaxFixedRecordLength=0xF00)710e6d15924SDimitry Andric emitNullTerminatedSymbolName(MCStreamer &OS, StringRef S,
711eb11fae6SDimitry Andric                              unsigned MaxFixedRecordLength = 0xF00) {
712b915e9e0SDimitry Andric   // The maximum CV record length is 0xFF00. Most of the strings we emit appear
713b915e9e0SDimitry Andric   // after a fixed length portion of the record. The fixed length portion should
714b915e9e0SDimitry Andric   // always be less than 0xF00 (3840) bytes, so truncate the string so that the
715b915e9e0SDimitry Andric   // overall record size is less than the maximum allowed.
716b915e9e0SDimitry Andric   SmallString<32> NullTerminatedString(
717b915e9e0SDimitry Andric       S.take_front(MaxRecordLength - MaxFixedRecordLength - 1));
71801095a5dSDimitry Andric   NullTerminatedString.push_back('\0');
719cfca06d7SDimitry Andric   OS.emitBytes(NullTerminatedString);
72001095a5dSDimitry Andric }
72101095a5dSDimitry Andric 
emitTypeInformation()72201095a5dSDimitry Andric void CodeViewDebug::emitTypeInformation() {
72301095a5dSDimitry Andric   if (TypeTable.empty())
72401095a5dSDimitry Andric     return;
72501095a5dSDimitry Andric 
726eb11fae6SDimitry Andric   // Start the .debug$T or .debug$P section with 0x4.
727145449b1SDimitry Andric   OS.switchSection(Asm->getObjFileLowering().getCOFFDebugTypesSection());
72801095a5dSDimitry Andric   emitCodeViewMagicVersion();
72901095a5dSDimitry Andric 
730b5630dbaSDimitry Andric   TypeTableCollection Table(TypeTable.records());
731e6d15924SDimitry Andric   TypeVisitorCallbackPipeline Pipeline;
732e6d15924SDimitry Andric 
733e6d15924SDimitry Andric   // To emit type record using Codeview MCStreamer adapter
7341d5ae102SDimitry Andric   CVMCAdapter CVMCOS(OS, Table);
735e6d15924SDimitry Andric   TypeRecordMapping typeMapping(CVMCOS);
736e6d15924SDimitry Andric   Pipeline.addCallbackToPipeline(typeMapping);
737e6d15924SDimitry Andric 
738e3b55780SDimitry Andric   std::optional<TypeIndex> B = Table.getFirst();
739b5630dbaSDimitry Andric   while (B) {
740b5630dbaSDimitry Andric     // This will fail if the record data is invalid.
741b5630dbaSDimitry Andric     CVType Record = Table.getType(*B);
742b5630dbaSDimitry Andric 
743e6d15924SDimitry Andric     Error E = codeview::visitTypeRecord(Record, *B, Pipeline);
744e6d15924SDimitry Andric 
74501095a5dSDimitry Andric     if (E) {
74601095a5dSDimitry Andric       logAllUnhandledErrors(std::move(E), errs(), "error: ");
74701095a5dSDimitry Andric       llvm_unreachable("produced malformed type record");
74801095a5dSDimitry Andric     }
749e6d15924SDimitry Andric 
750b5630dbaSDimitry Andric     B = Table.getNext(*B);
75101095a5dSDimitry Andric   }
75201095a5dSDimitry Andric }
75301095a5dSDimitry Andric 
emitTypeGlobalHashes()754044eb2f6SDimitry Andric void CodeViewDebug::emitTypeGlobalHashes() {
755044eb2f6SDimitry Andric   if (TypeTable.empty())
756044eb2f6SDimitry Andric     return;
757044eb2f6SDimitry Andric 
758044eb2f6SDimitry Andric   // Start the .debug$H section with the version and hash algorithm, currently
759044eb2f6SDimitry Andric   // hardcoded to version 0, SHA1.
760145449b1SDimitry Andric   OS.switchSection(Asm->getObjFileLowering().getCOFFGlobalTypeHashesSection());
761044eb2f6SDimitry Andric 
762e3b55780SDimitry Andric   OS.emitValueToAlignment(Align(4));
763044eb2f6SDimitry Andric   OS.AddComment("Magic");
764cfca06d7SDimitry Andric   OS.emitInt32(COFF::DEBUG_HASHES_SECTION_MAGIC);
765044eb2f6SDimitry Andric   OS.AddComment("Section Version");
766cfca06d7SDimitry Andric   OS.emitInt16(0);
767044eb2f6SDimitry Andric   OS.AddComment("Hash Algorithm");
768e3b55780SDimitry Andric   OS.emitInt16(uint16_t(GlobalTypeHashAlg::BLAKE3));
769044eb2f6SDimitry Andric 
770044eb2f6SDimitry Andric   TypeIndex TI(TypeIndex::FirstNonSimpleIndex);
771044eb2f6SDimitry Andric   for (const auto &GHR : TypeTable.hashes()) {
772044eb2f6SDimitry Andric     if (OS.isVerboseAsm()) {
773044eb2f6SDimitry Andric       // Emit an EOL-comment describing which TypeIndex this hash corresponds
774044eb2f6SDimitry Andric       // to, as well as the stringified SHA1 hash.
775044eb2f6SDimitry Andric       SmallString<32> Comment;
776044eb2f6SDimitry Andric       raw_svector_ostream CommentOS(Comment);
777044eb2f6SDimitry Andric       CommentOS << formatv("{0:X+} [{1}]", TI.getIndex(), GHR);
778044eb2f6SDimitry Andric       OS.AddComment(Comment);
779044eb2f6SDimitry Andric       ++TI;
780044eb2f6SDimitry Andric     }
781eb11fae6SDimitry Andric     assert(GHR.Hash.size() == 8);
782044eb2f6SDimitry Andric     StringRef S(reinterpret_cast<const char *>(GHR.Hash.data()),
783044eb2f6SDimitry Andric                 GHR.Hash.size());
784cfca06d7SDimitry Andric     OS.emitBinaryData(S);
785044eb2f6SDimitry Andric   }
786044eb2f6SDimitry Andric }
787b915e9e0SDimitry Andric 
emitObjName()78877fc4c14SDimitry Andric void CodeViewDebug::emitObjName() {
78977fc4c14SDimitry Andric   MCSymbol *CompilerEnd = beginSymbolRecord(SymbolKind::S_OBJNAME);
79077fc4c14SDimitry Andric 
79177fc4c14SDimitry Andric   StringRef PathRef(Asm->TM.Options.ObjectFilenameForDebug);
79277fc4c14SDimitry Andric   llvm::SmallString<256> PathStore(PathRef);
79377fc4c14SDimitry Andric 
79477fc4c14SDimitry Andric   if (PathRef.empty() || PathRef == "-") {
79577fc4c14SDimitry Andric     // Don't emit the filename if we're writing to stdout or to /dev/null.
79677fc4c14SDimitry Andric     PathRef = {};
79777fc4c14SDimitry Andric   } else {
79877fc4c14SDimitry Andric     PathRef = PathStore;
79977fc4c14SDimitry Andric   }
80077fc4c14SDimitry Andric 
80177fc4c14SDimitry Andric   OS.AddComment("Signature");
80277fc4c14SDimitry Andric   OS.emitIntValue(0, 4);
80377fc4c14SDimitry Andric 
80477fc4c14SDimitry Andric   OS.AddComment("Object name");
80577fc4c14SDimitry Andric   emitNullTerminatedSymbolName(OS, PathRef);
80677fc4c14SDimitry Andric 
80777fc4c14SDimitry Andric   endSymbolRecord(CompilerEnd);
80877fc4c14SDimitry Andric }
80977fc4c14SDimitry Andric 
810044eb2f6SDimitry Andric namespace {
811b915e9e0SDimitry Andric struct Version {
812b915e9e0SDimitry Andric   int Part[4];
813b915e9e0SDimitry Andric };
814044eb2f6SDimitry Andric } // end anonymous namespace
815b915e9e0SDimitry Andric 
816b915e9e0SDimitry Andric // Takes a StringRef like "clang 4.0.0.0 (other nonsense 123)" and parses out
817b915e9e0SDimitry Andric // the version number.
parseVersion(StringRef Name)818b915e9e0SDimitry Andric static Version parseVersion(StringRef Name) {
819b915e9e0SDimitry Andric   Version V = {{0}};
820b915e9e0SDimitry Andric   int N = 0;
821b915e9e0SDimitry Andric   for (const char C : Name) {
822b915e9e0SDimitry Andric     if (isdigit(C)) {
823b915e9e0SDimitry Andric       V.Part[N] *= 10;
824b915e9e0SDimitry Andric       V.Part[N] += C - '0';
825145449b1SDimitry Andric       V.Part[N] =
826145449b1SDimitry Andric           std::min<int>(V.Part[N], std::numeric_limits<uint16_t>::max());
827b915e9e0SDimitry Andric     } else if (C == '.') {
828b915e9e0SDimitry Andric       ++N;
829b915e9e0SDimitry Andric       if (N >= 4)
830b915e9e0SDimitry Andric         return V;
831b915e9e0SDimitry Andric     } else if (N > 0)
832b915e9e0SDimitry Andric       return V;
833b915e9e0SDimitry Andric   }
834b915e9e0SDimitry Andric   return V;
835b915e9e0SDimitry Andric }
836b915e9e0SDimitry Andric 
emitCompilerInformation()837b915e9e0SDimitry Andric void CodeViewDebug::emitCompilerInformation() {
838d8e91e46SDimitry Andric   MCSymbol *CompilerEnd = beginSymbolRecord(SymbolKind::S_COMPILE3);
839b915e9e0SDimitry Andric   uint32_t Flags = 0;
840b915e9e0SDimitry Andric 
841b915e9e0SDimitry Andric   // The low byte of the flags indicates the source language.
842c0981da4SDimitry Andric   Flags = CurrentSourceLanguage;
843b915e9e0SDimitry Andric   // TODO:  Figure out which other flags need to be set.
844344a3780SDimitry Andric   if (MMI->getModule()->getProfileSummary(/*IsCS*/ false) != nullptr) {
845344a3780SDimitry Andric     Flags |= static_cast<uint32_t>(CompileSym3Flags::PGO);
846344a3780SDimitry Andric   }
8476f8fc217SDimitry Andric   using ArchType = llvm::Triple::ArchType;
8486f8fc217SDimitry Andric   ArchType Arch = Triple(MMI->getModule()->getTargetTriple()).getArch();
8496f8fc217SDimitry Andric   if (Asm->TM.Options.Hotpatch || Arch == ArchType::thumb ||
8506f8fc217SDimitry Andric       Arch == ArchType::aarch64) {
8516f8fc217SDimitry Andric     Flags |= static_cast<uint32_t>(CompileSym3Flags::HotPatch);
8526f8fc217SDimitry Andric   }
853b915e9e0SDimitry Andric 
854b915e9e0SDimitry Andric   OS.AddComment("Flags and language");
855cfca06d7SDimitry Andric   OS.emitInt32(Flags);
856b915e9e0SDimitry Andric 
857b915e9e0SDimitry Andric   OS.AddComment("CPUType");
858cfca06d7SDimitry Andric   OS.emitInt16(static_cast<uint64_t>(TheCPU));
859b915e9e0SDimitry Andric 
860c0981da4SDimitry Andric   NamedMDNode *CUs = MMI->getModule()->getNamedMetadata("llvm.dbg.cu");
861c0981da4SDimitry Andric   const MDNode *Node = *CUs->operands().begin();
862c0981da4SDimitry Andric   const auto *CU = cast<DICompileUnit>(Node);
863c0981da4SDimitry Andric 
864b915e9e0SDimitry Andric   StringRef CompilerVersion = CU->getProducer();
865b915e9e0SDimitry Andric   Version FrontVer = parseVersion(CompilerVersion);
866b915e9e0SDimitry Andric   OS.AddComment("Frontend version");
8676f8fc217SDimitry Andric   for (int N : FrontVer.Part) {
868344a3780SDimitry Andric     OS.emitInt16(N);
8696f8fc217SDimitry Andric   }
870b915e9e0SDimitry Andric 
871b915e9e0SDimitry Andric   // Some Microsoft tools, like Binscope, expect a backend version number of at
872b915e9e0SDimitry Andric   // least 8.something, so we'll coerce the LLVM version into a form that
873b915e9e0SDimitry Andric   // guarantees it'll be big enough without really lying about the version.
874b915e9e0SDimitry Andric   int Major = 1000 * LLVM_VERSION_MAJOR +
875b915e9e0SDimitry Andric               10 * LLVM_VERSION_MINOR +
876b915e9e0SDimitry Andric               LLVM_VERSION_PATCH;
877b915e9e0SDimitry Andric   // Clamp it for builds that use unusually large version numbers.
878b915e9e0SDimitry Andric   Major = std::min<int>(Major, std::numeric_limits<uint16_t>::max());
879b915e9e0SDimitry Andric   Version BackVer = {{ Major, 0, 0, 0 }};
880b915e9e0SDimitry Andric   OS.AddComment("Backend version");
881344a3780SDimitry Andric   for (int N : BackVer.Part)
882344a3780SDimitry Andric     OS.emitInt16(N);
883b915e9e0SDimitry Andric 
884b915e9e0SDimitry Andric   OS.AddComment("Null-terminated compiler version string");
885b915e9e0SDimitry Andric   emitNullTerminatedSymbolName(OS, CompilerVersion);
886b915e9e0SDimitry Andric 
887d8e91e46SDimitry Andric   endSymbolRecord(CompilerEnd);
888d8e91e46SDimitry Andric }
889d8e91e46SDimitry Andric 
getStringIdTypeIdx(GlobalTypeTableBuilder & TypeTable,StringRef S)890d8e91e46SDimitry Andric static TypeIndex getStringIdTypeIdx(GlobalTypeTableBuilder &TypeTable,
891d8e91e46SDimitry Andric                                     StringRef S) {
892d8e91e46SDimitry Andric   StringIdRecord SIR(TypeIndex(0x0), S);
893d8e91e46SDimitry Andric   return TypeTable.writeLeafType(SIR);
894d8e91e46SDimitry Andric }
895d8e91e46SDimitry Andric 
flattenCommandLine(ArrayRef<std::string> Args,StringRef MainFilename)8966f8fc217SDimitry Andric static std::string flattenCommandLine(ArrayRef<std::string> Args,
8976f8fc217SDimitry Andric                                       StringRef MainFilename) {
8986f8fc217SDimitry Andric   std::string FlatCmdLine;
8996f8fc217SDimitry Andric   raw_string_ostream OS(FlatCmdLine);
9006f8fc217SDimitry Andric   bool PrintedOneArg = false;
9016f8fc217SDimitry Andric   if (!StringRef(Args[0]).contains("-cc1")) {
9026f8fc217SDimitry Andric     llvm::sys::printArg(OS, "-cc1", /*Quote=*/true);
9036f8fc217SDimitry Andric     PrintedOneArg = true;
9046f8fc217SDimitry Andric   }
9056f8fc217SDimitry Andric   for (unsigned i = 0; i < Args.size(); i++) {
9066f8fc217SDimitry Andric     StringRef Arg = Args[i];
9076f8fc217SDimitry Andric     if (Arg.empty())
9086f8fc217SDimitry Andric       continue;
9096f8fc217SDimitry Andric     if (Arg == "-main-file-name" || Arg == "-o") {
9106f8fc217SDimitry Andric       i++; // Skip this argument and next one.
9116f8fc217SDimitry Andric       continue;
9126f8fc217SDimitry Andric     }
913b1c73532SDimitry Andric     if (Arg.starts_with("-object-file-name") || Arg == MainFilename)
9146f8fc217SDimitry Andric       continue;
915e3b55780SDimitry Andric     // Skip fmessage-length for reproduciability.
916b1c73532SDimitry Andric     if (Arg.starts_with("-fmessage-length"))
917e3b55780SDimitry Andric       continue;
9186f8fc217SDimitry Andric     if (PrintedOneArg)
9196f8fc217SDimitry Andric       OS << " ";
9206f8fc217SDimitry Andric     llvm::sys::printArg(OS, Arg, /*Quote=*/true);
9216f8fc217SDimitry Andric     PrintedOneArg = true;
9226f8fc217SDimitry Andric   }
9236f8fc217SDimitry Andric   OS.flush();
9246f8fc217SDimitry Andric   return FlatCmdLine;
9256f8fc217SDimitry Andric }
9266f8fc217SDimitry Andric 
emitBuildInfo()927d8e91e46SDimitry Andric void CodeViewDebug::emitBuildInfo() {
928d8e91e46SDimitry Andric   // First, make LF_BUILDINFO. It's a sequence of strings with various bits of
929d8e91e46SDimitry Andric   // build info. The known prefix is:
930d8e91e46SDimitry Andric   // - Absolute path of current directory
931d8e91e46SDimitry Andric   // - Compiler path
932d8e91e46SDimitry Andric   // - Main source file path, relative to CWD or absolute
933d8e91e46SDimitry Andric   // - Type server PDB file
934d8e91e46SDimitry Andric   // - Canonical compiler command line
935d8e91e46SDimitry Andric   // If frontend and backend compilation are separated (think llc or LTO), it's
936d8e91e46SDimitry Andric   // not clear if the compiler path should refer to the executable for the
937d8e91e46SDimitry Andric   // frontend or the backend. Leave it blank for now.
938d8e91e46SDimitry Andric   TypeIndex BuildInfoArgs[BuildInfoRecord::MaxArgs] = {};
939d8e91e46SDimitry Andric   NamedMDNode *CUs = MMI->getModule()->getNamedMetadata("llvm.dbg.cu");
940d8e91e46SDimitry Andric   const MDNode *Node = *CUs->operands().begin(); // FIXME: Multiple CUs.
941d8e91e46SDimitry Andric   const auto *CU = cast<DICompileUnit>(Node);
942d8e91e46SDimitry Andric   const DIFile *MainSourceFile = CU->getFile();
943d8e91e46SDimitry Andric   BuildInfoArgs[BuildInfoRecord::CurrentDirectory] =
944d8e91e46SDimitry Andric       getStringIdTypeIdx(TypeTable, MainSourceFile->getDirectory());
945d8e91e46SDimitry Andric   BuildInfoArgs[BuildInfoRecord::SourceFile] =
946d8e91e46SDimitry Andric       getStringIdTypeIdx(TypeTable, MainSourceFile->getFilename());
9476f8fc217SDimitry Andric   // FIXME: PDB is intentionally blank unless we implement /Zi type servers.
9486f8fc217SDimitry Andric   BuildInfoArgs[BuildInfoRecord::TypeServerPDB] =
9496f8fc217SDimitry Andric       getStringIdTypeIdx(TypeTable, "");
9506f8fc217SDimitry Andric   if (Asm->TM.Options.MCOptions.Argv0 != nullptr) {
9516f8fc217SDimitry Andric     BuildInfoArgs[BuildInfoRecord::BuildTool] =
9526f8fc217SDimitry Andric         getStringIdTypeIdx(TypeTable, Asm->TM.Options.MCOptions.Argv0);
9536f8fc217SDimitry Andric     BuildInfoArgs[BuildInfoRecord::CommandLine] = getStringIdTypeIdx(
9546f8fc217SDimitry Andric         TypeTable, flattenCommandLine(Asm->TM.Options.MCOptions.CommandLineArgs,
9556f8fc217SDimitry Andric                                       MainSourceFile->getFilename()));
9566f8fc217SDimitry Andric   }
957d8e91e46SDimitry Andric   BuildInfoRecord BIR(BuildInfoArgs);
958d8e91e46SDimitry Andric   TypeIndex BuildInfoIndex = TypeTable.writeLeafType(BIR);
959d8e91e46SDimitry Andric 
960d8e91e46SDimitry Andric   // Make a new .debug$S subsection for the S_BUILDINFO record, which points
961d8e91e46SDimitry Andric   // from the module symbols into the type stream.
962d8e91e46SDimitry Andric   MCSymbol *BISubsecEnd = beginCVSubsection(DebugSubsectionKind::Symbols);
963d8e91e46SDimitry Andric   MCSymbol *BIEnd = beginSymbolRecord(SymbolKind::S_BUILDINFO);
964d8e91e46SDimitry Andric   OS.AddComment("LF_BUILDINFO index");
965cfca06d7SDimitry Andric   OS.emitInt32(BuildInfoIndex.getIndex());
966d8e91e46SDimitry Andric   endSymbolRecord(BIEnd);
967d8e91e46SDimitry Andric   endCVSubsection(BISubsecEnd);
968b915e9e0SDimitry Andric }
969b915e9e0SDimitry Andric 
emitInlineeLinesSubsection()97001095a5dSDimitry Andric void CodeViewDebug::emitInlineeLinesSubsection() {
97101095a5dSDimitry Andric   if (InlinedSubprograms.empty())
97201095a5dSDimitry Andric     return;
97301095a5dSDimitry Andric 
97401095a5dSDimitry Andric   OS.AddComment("Inlinee lines subsection");
975ee2f195dSDimitry Andric   MCSymbol *InlineEnd = beginCVSubsection(DebugSubsectionKind::InlineeLines);
97601095a5dSDimitry Andric 
977044eb2f6SDimitry Andric   // We emit the checksum info for files.  This is used by debuggers to
978044eb2f6SDimitry Andric   // determine if a pdb matches the source before loading it.  Visual Studio,
979044eb2f6SDimitry Andric   // for instance, will display a warning that the breakpoints are not valid if
980044eb2f6SDimitry Andric   // the pdb does not match the source.
98101095a5dSDimitry Andric   OS.AddComment("Inlinee lines signature");
982cfca06d7SDimitry Andric   OS.emitInt32(unsigned(InlineeLinesSignature::Normal));
98301095a5dSDimitry Andric 
98401095a5dSDimitry Andric   for (const DISubprogram *SP : InlinedSubprograms) {
98501095a5dSDimitry Andric     assert(TypeIndices.count({SP, nullptr}));
98601095a5dSDimitry Andric     TypeIndex InlineeIdx = TypeIndices[{SP, nullptr}];
98701095a5dSDimitry Andric 
988145449b1SDimitry Andric     OS.addBlankLine();
98901095a5dSDimitry Andric     unsigned FileId = maybeRecordFile(SP->getFile());
990a303c417SDimitry Andric     OS.AddComment("Inlined function " + SP->getName() + " starts at " +
99101095a5dSDimitry Andric                   SP->getFilename() + Twine(':') + Twine(SP->getLine()));
992145449b1SDimitry Andric     OS.addBlankLine();
99301095a5dSDimitry Andric     OS.AddComment("Type index of inlined function");
994cfca06d7SDimitry Andric     OS.emitInt32(InlineeIdx.getIndex());
99501095a5dSDimitry Andric     OS.AddComment("Offset into filechecksum table");
996cfca06d7SDimitry Andric     OS.emitCVFileChecksumOffsetDirective(FileId);
99701095a5dSDimitry Andric     OS.AddComment("Starting line number");
998cfca06d7SDimitry Andric     OS.emitInt32(SP->getLine());
99901095a5dSDimitry Andric   }
100001095a5dSDimitry Andric 
100101095a5dSDimitry Andric   endCVSubsection(InlineEnd);
100201095a5dSDimitry Andric }
100301095a5dSDimitry Andric 
emitInlinedCallSite(const FunctionInfo & FI,const DILocation * InlinedAt,const InlineSite & Site)100401095a5dSDimitry Andric void CodeViewDebug::emitInlinedCallSite(const FunctionInfo &FI,
100501095a5dSDimitry Andric                                         const DILocation *InlinedAt,
100601095a5dSDimitry Andric                                         const InlineSite &Site) {
100701095a5dSDimitry Andric   assert(TypeIndices.count({Site.Inlinee, nullptr}));
100801095a5dSDimitry Andric   TypeIndex InlineeIdx = TypeIndices[{Site.Inlinee, nullptr}];
100901095a5dSDimitry Andric 
101001095a5dSDimitry Andric   // SymbolRecord
1011d8e91e46SDimitry Andric   MCSymbol *InlineEnd = beginSymbolRecord(SymbolKind::S_INLINESITE);
101201095a5dSDimitry Andric 
101301095a5dSDimitry Andric   OS.AddComment("PtrParent");
1014cfca06d7SDimitry Andric   OS.emitInt32(0);
101501095a5dSDimitry Andric   OS.AddComment("PtrEnd");
1016cfca06d7SDimitry Andric   OS.emitInt32(0);
101701095a5dSDimitry Andric   OS.AddComment("Inlinee type index");
1018cfca06d7SDimitry Andric   OS.emitInt32(InlineeIdx.getIndex());
101901095a5dSDimitry Andric 
102001095a5dSDimitry Andric   unsigned FileId = maybeRecordFile(Site.Inlinee->getFile());
102101095a5dSDimitry Andric   unsigned StartLineNum = Site.Inlinee->getLine();
102201095a5dSDimitry Andric 
1023cfca06d7SDimitry Andric   OS.emitCVInlineLinetableDirective(Site.SiteFuncId, FileId, StartLineNum,
1024b915e9e0SDimitry Andric                                     FI.Begin, FI.End);
102501095a5dSDimitry Andric 
1026d8e91e46SDimitry Andric   endSymbolRecord(InlineEnd);
102701095a5dSDimitry Andric 
1028d8e91e46SDimitry Andric   emitLocalVariableList(FI, Site.InlinedLocals);
102901095a5dSDimitry Andric 
103001095a5dSDimitry Andric   // Recurse on child inlined call sites before closing the scope.
103101095a5dSDimitry Andric   for (const DILocation *ChildSite : Site.ChildSites) {
103201095a5dSDimitry Andric     auto I = FI.InlineSites.find(ChildSite);
103301095a5dSDimitry Andric     assert(I != FI.InlineSites.end() &&
103401095a5dSDimitry Andric            "child site not in function inline site map");
103501095a5dSDimitry Andric     emitInlinedCallSite(FI, ChildSite, I->second);
103601095a5dSDimitry Andric   }
103701095a5dSDimitry Andric 
103801095a5dSDimitry Andric   // Close the scope.
1039d8e91e46SDimitry Andric   emitEndSymbolRecord(SymbolKind::S_INLINESITE_END);
104001095a5dSDimitry Andric }
104101095a5dSDimitry Andric 
switchToDebugSectionForSymbol(const MCSymbol * GVSym)104201095a5dSDimitry Andric void CodeViewDebug::switchToDebugSectionForSymbol(const MCSymbol *GVSym) {
104301095a5dSDimitry Andric   // If we have a symbol, it may be in a section that is COMDAT. If so, find the
104401095a5dSDimitry Andric   // comdat key. A section may be comdat because of -ffunction-sections or
104501095a5dSDimitry Andric   // because it is comdat in the IR.
104601095a5dSDimitry Andric   MCSectionCOFF *GVSec =
104701095a5dSDimitry Andric       GVSym ? dyn_cast<MCSectionCOFF>(&GVSym->getSection()) : nullptr;
104801095a5dSDimitry Andric   const MCSymbol *KeySym = GVSec ? GVSec->getCOMDATSymbol() : nullptr;
104901095a5dSDimitry Andric 
105001095a5dSDimitry Andric   MCSectionCOFF *DebugSec = cast<MCSectionCOFF>(
105101095a5dSDimitry Andric       Asm->getObjFileLowering().getCOFFDebugSymbolsSection());
105201095a5dSDimitry Andric   DebugSec = OS.getContext().getAssociativeCOFFSection(DebugSec, KeySym);
105301095a5dSDimitry Andric 
1054145449b1SDimitry Andric   OS.switchSection(DebugSec);
105501095a5dSDimitry Andric 
105601095a5dSDimitry Andric   // Emit the magic version number if this is the first time we've switched to
105701095a5dSDimitry Andric   // this section.
105801095a5dSDimitry Andric   if (ComdatDebugSections.insert(DebugSec).second)
105901095a5dSDimitry Andric     emitCodeViewMagicVersion();
106001095a5dSDimitry Andric }
106101095a5dSDimitry Andric 
1062eb11fae6SDimitry Andric // Emit an S_THUNK32/S_END symbol pair for a thunk routine.
1063eb11fae6SDimitry Andric // The only supported thunk ordinal is currently the standard type.
emitDebugInfoForThunk(const Function * GV,FunctionInfo & FI,const MCSymbol * Fn)1064eb11fae6SDimitry Andric void CodeViewDebug::emitDebugInfoForThunk(const Function *GV,
1065eb11fae6SDimitry Andric                                           FunctionInfo &FI,
1066eb11fae6SDimitry Andric                                           const MCSymbol *Fn) {
1067cfca06d7SDimitry Andric   std::string FuncName =
1068cfca06d7SDimitry Andric       std::string(GlobalValue::dropLLVMManglingEscape(GV->getName()));
1069eb11fae6SDimitry Andric   const ThunkOrdinal ordinal = ThunkOrdinal::Standard; // Only supported kind.
1070eb11fae6SDimitry Andric 
1071eb11fae6SDimitry Andric   OS.AddComment("Symbol subsection for " + Twine(FuncName));
1072eb11fae6SDimitry Andric   MCSymbol *SymbolsEnd = beginCVSubsection(DebugSubsectionKind::Symbols);
1073eb11fae6SDimitry Andric 
1074eb11fae6SDimitry Andric   // Emit S_THUNK32
1075d8e91e46SDimitry Andric   MCSymbol *ThunkRecordEnd = beginSymbolRecord(SymbolKind::S_THUNK32);
1076eb11fae6SDimitry Andric   OS.AddComment("PtrParent");
1077cfca06d7SDimitry Andric   OS.emitInt32(0);
1078eb11fae6SDimitry Andric   OS.AddComment("PtrEnd");
1079cfca06d7SDimitry Andric   OS.emitInt32(0);
1080eb11fae6SDimitry Andric   OS.AddComment("PtrNext");
1081cfca06d7SDimitry Andric   OS.emitInt32(0);
1082eb11fae6SDimitry Andric   OS.AddComment("Thunk section relative address");
1083145449b1SDimitry Andric   OS.emitCOFFSecRel32(Fn, /*Offset=*/0);
1084eb11fae6SDimitry Andric   OS.AddComment("Thunk section index");
1085145449b1SDimitry Andric   OS.emitCOFFSectionIndex(Fn);
1086eb11fae6SDimitry Andric   OS.AddComment("Code size");
1087eb11fae6SDimitry Andric   OS.emitAbsoluteSymbolDiff(FI.End, Fn, 2);
1088eb11fae6SDimitry Andric   OS.AddComment("Ordinal");
1089cfca06d7SDimitry Andric   OS.emitInt8(unsigned(ordinal));
1090eb11fae6SDimitry Andric   OS.AddComment("Function name");
1091eb11fae6SDimitry Andric   emitNullTerminatedSymbolName(OS, FuncName);
1092eb11fae6SDimitry Andric   // Additional fields specific to the thunk ordinal would go here.
1093d8e91e46SDimitry Andric   endSymbolRecord(ThunkRecordEnd);
1094eb11fae6SDimitry Andric 
1095eb11fae6SDimitry Andric   // Local variables/inlined routines are purposely omitted here.  The point of
1096eb11fae6SDimitry Andric   // marking this as a thunk is so Visual Studio will NOT stop in this routine.
1097eb11fae6SDimitry Andric 
1098eb11fae6SDimitry Andric   // Emit S_PROC_ID_END
1099d8e91e46SDimitry Andric   emitEndSymbolRecord(SymbolKind::S_PROC_ID_END);
1100eb11fae6SDimitry Andric 
1101eb11fae6SDimitry Andric   endCVSubsection(SymbolsEnd);
1102eb11fae6SDimitry Andric }
1103eb11fae6SDimitry Andric 
emitDebugInfoForFunction(const Function * GV,FunctionInfo & FI)110401095a5dSDimitry Andric void CodeViewDebug::emitDebugInfoForFunction(const Function *GV,
110501095a5dSDimitry Andric                                              FunctionInfo &FI) {
1106eb11fae6SDimitry Andric   // For each function there is a separate subsection which holds the PC to
1107eb11fae6SDimitry Andric   // file:line table.
110801095a5dSDimitry Andric   const MCSymbol *Fn = Asm->getSymbol(GV);
110901095a5dSDimitry Andric   assert(Fn);
111001095a5dSDimitry Andric 
111101095a5dSDimitry Andric   // Switch to the to a comdat section, if appropriate.
111201095a5dSDimitry Andric   switchToDebugSectionForSymbol(Fn);
111301095a5dSDimitry Andric 
111401095a5dSDimitry Andric   std::string FuncName;
111501095a5dSDimitry Andric   auto *SP = GV->getSubprogram();
1116a7fe922bSDimitry Andric   assert(SP);
111701095a5dSDimitry Andric   setCurrentSubprogram(SP);
111801095a5dSDimitry Andric 
1119eb11fae6SDimitry Andric   if (SP->isThunk()) {
1120eb11fae6SDimitry Andric     emitDebugInfoForThunk(GV, FI, Fn);
1121eb11fae6SDimitry Andric     return;
1122eb11fae6SDimitry Andric   }
1123eb11fae6SDimitry Andric 
112401095a5dSDimitry Andric   // If we have a display name, build the fully qualified name by walking the
112501095a5dSDimitry Andric   // chain of scopes.
1126a303c417SDimitry Andric   if (!SP->getName().empty())
1127e6d15924SDimitry Andric     FuncName = getFullyQualifiedName(SP->getScope(), SP->getName());
112801095a5dSDimitry Andric 
112901095a5dSDimitry Andric   // If our DISubprogram name is empty, use the mangled name.
113001095a5dSDimitry Andric   if (FuncName.empty())
1131cfca06d7SDimitry Andric     FuncName = std::string(GlobalValue::dropLLVMManglingEscape(GV->getName()));
113201095a5dSDimitry Andric 
1133044eb2f6SDimitry Andric   // Emit FPO data, but only on 32-bit x86. No other platforms use it.
1134044eb2f6SDimitry Andric   if (Triple(MMI->getModule()->getTargetTriple()).getArch() == Triple::x86)
1135145449b1SDimitry Andric     OS.emitCVFPOData(Fn);
1136044eb2f6SDimitry Andric 
113701095a5dSDimitry Andric   // Emit a symbol subsection, required by VS2012+ to find function boundaries.
113801095a5dSDimitry Andric   OS.AddComment("Symbol subsection for " + Twine(FuncName));
1139ee2f195dSDimitry Andric   MCSymbol *SymbolsEnd = beginCVSubsection(DebugSubsectionKind::Symbols);
114001095a5dSDimitry Andric   {
1141d8e91e46SDimitry Andric     SymbolKind ProcKind = GV->hasLocalLinkage() ? SymbolKind::S_LPROC32_ID
1142d8e91e46SDimitry Andric                                                 : SymbolKind::S_GPROC32_ID;
1143d8e91e46SDimitry Andric     MCSymbol *ProcRecordEnd = beginSymbolRecord(ProcKind);
114401095a5dSDimitry Andric 
114501095a5dSDimitry Andric     // These fields are filled in by tools like CVPACK which run after the fact.
114601095a5dSDimitry Andric     OS.AddComment("PtrParent");
1147cfca06d7SDimitry Andric     OS.emitInt32(0);
114801095a5dSDimitry Andric     OS.AddComment("PtrEnd");
1149cfca06d7SDimitry Andric     OS.emitInt32(0);
115001095a5dSDimitry Andric     OS.AddComment("PtrNext");
1151cfca06d7SDimitry Andric     OS.emitInt32(0);
115201095a5dSDimitry Andric     // This is the important bit that tells the debugger where the function
115301095a5dSDimitry Andric     // code is located and what's its size:
115401095a5dSDimitry Andric     OS.AddComment("Code size");
115501095a5dSDimitry Andric     OS.emitAbsoluteSymbolDiff(FI.End, Fn, 4);
115601095a5dSDimitry Andric     OS.AddComment("Offset after prologue");
1157cfca06d7SDimitry Andric     OS.emitInt32(0);
115801095a5dSDimitry Andric     OS.AddComment("Offset before epilogue");
1159cfca06d7SDimitry Andric     OS.emitInt32(0);
116001095a5dSDimitry Andric     OS.AddComment("Function type index");
1161cfca06d7SDimitry Andric     OS.emitInt32(getFuncIdForSubprogram(GV->getSubprogram()).getIndex());
116201095a5dSDimitry Andric     OS.AddComment("Function section relative address");
1163145449b1SDimitry Andric     OS.emitCOFFSecRel32(Fn, /*Offset=*/0);
116401095a5dSDimitry Andric     OS.AddComment("Function section index");
1165145449b1SDimitry Andric     OS.emitCOFFSectionIndex(Fn);
116601095a5dSDimitry Andric     OS.AddComment("Flags");
11677fa27ce4SDimitry Andric     ProcSymFlags ProcFlags = ProcSymFlags::HasOptimizedDebugInfo;
11687fa27ce4SDimitry Andric     if (FI.HasFramePointer)
11697fa27ce4SDimitry Andric       ProcFlags |= ProcSymFlags::HasFP;
11707fa27ce4SDimitry Andric     if (GV->hasFnAttribute(Attribute::NoReturn))
11717fa27ce4SDimitry Andric       ProcFlags |= ProcSymFlags::IsNoReturn;
11727fa27ce4SDimitry Andric     if (GV->hasFnAttribute(Attribute::NoInline))
11737fa27ce4SDimitry Andric       ProcFlags |= ProcSymFlags::IsNoInline;
11747fa27ce4SDimitry Andric     OS.emitInt8(static_cast<uint8_t>(ProcFlags));
117501095a5dSDimitry Andric     // Emit the function display name as a null-terminated string.
117601095a5dSDimitry Andric     OS.AddComment("Function name");
117701095a5dSDimitry Andric     // Truncate the name so we won't overflow the record length field.
117801095a5dSDimitry Andric     emitNullTerminatedSymbolName(OS, FuncName);
1179d8e91e46SDimitry Andric     endSymbolRecord(ProcRecordEnd);
118001095a5dSDimitry Andric 
1181d8e91e46SDimitry Andric     MCSymbol *FrameProcEnd = beginSymbolRecord(SymbolKind::S_FRAMEPROC);
1182d8e91e46SDimitry Andric     // Subtract out the CSR size since MSVC excludes that and we include it.
1183d8e91e46SDimitry Andric     OS.AddComment("FrameSize");
1184cfca06d7SDimitry Andric     OS.emitInt32(FI.FrameSize - FI.CSRSize);
1185d8e91e46SDimitry Andric     OS.AddComment("Padding");
1186cfca06d7SDimitry Andric     OS.emitInt32(0);
1187d8e91e46SDimitry Andric     OS.AddComment("Offset of padding");
1188cfca06d7SDimitry Andric     OS.emitInt32(0);
1189d8e91e46SDimitry Andric     OS.AddComment("Bytes of callee saved registers");
1190cfca06d7SDimitry Andric     OS.emitInt32(FI.CSRSize);
1191d8e91e46SDimitry Andric     OS.AddComment("Exception handler offset");
1192cfca06d7SDimitry Andric     OS.emitInt32(0);
1193d8e91e46SDimitry Andric     OS.AddComment("Exception handler section");
1194cfca06d7SDimitry Andric     OS.emitInt16(0);
1195d8e91e46SDimitry Andric     OS.AddComment("Flags (defines frame register)");
1196cfca06d7SDimitry Andric     OS.emitInt32(uint32_t(FI.FrameProcOpts));
1197d8e91e46SDimitry Andric     endSymbolRecord(FrameProcEnd);
1198d8e91e46SDimitry Andric 
1199b1c73532SDimitry Andric     emitInlinees(FI.Inlinees);
1200d8e91e46SDimitry Andric     emitLocalVariableList(FI, FI.Locals);
1201d8e91e46SDimitry Andric     emitGlobalVariableList(FI.Globals);
1202eb11fae6SDimitry Andric     emitLexicalBlockList(FI.ChildBlocks, FI);
120301095a5dSDimitry Andric 
120401095a5dSDimitry Andric     // Emit inlined call site information. Only emit functions inlined directly
120501095a5dSDimitry Andric     // into the parent function. We'll emit the other sites recursively as part
120601095a5dSDimitry Andric     // of their parent inline site.
120701095a5dSDimitry Andric     for (const DILocation *InlinedAt : FI.ChildSites) {
120801095a5dSDimitry Andric       auto I = FI.InlineSites.find(InlinedAt);
120901095a5dSDimitry Andric       assert(I != FI.InlineSites.end() &&
121001095a5dSDimitry Andric              "child site not in function inline site map");
121101095a5dSDimitry Andric       emitInlinedCallSite(FI, InlinedAt, I->second);
121201095a5dSDimitry Andric     }
121301095a5dSDimitry Andric 
1214044eb2f6SDimitry Andric     for (auto Annot : FI.Annotations) {
1215044eb2f6SDimitry Andric       MCSymbol *Label = Annot.first;
1216044eb2f6SDimitry Andric       MDTuple *Strs = cast<MDTuple>(Annot.second);
1217d8e91e46SDimitry Andric       MCSymbol *AnnotEnd = beginSymbolRecord(SymbolKind::S_ANNOTATION);
1218145449b1SDimitry Andric       OS.emitCOFFSecRel32(Label, /*Offset=*/0);
1219044eb2f6SDimitry Andric       // FIXME: Make sure we don't overflow the max record size.
1220145449b1SDimitry Andric       OS.emitCOFFSectionIndex(Label);
1221cfca06d7SDimitry Andric       OS.emitInt16(Strs->getNumOperands());
1222044eb2f6SDimitry Andric       for (Metadata *MD : Strs->operands()) {
1223044eb2f6SDimitry Andric         // MDStrings are null terminated, so we can do EmitBytes and get the
1224044eb2f6SDimitry Andric         // nice .asciz directive.
1225044eb2f6SDimitry Andric         StringRef Str = cast<MDString>(MD)->getString();
1226044eb2f6SDimitry Andric         assert(Str.data()[Str.size()] == '\0' && "non-nullterminated MDString");
1227cfca06d7SDimitry Andric         OS.emitBytes(StringRef(Str.data(), Str.size() + 1));
1228044eb2f6SDimitry Andric       }
1229d8e91e46SDimitry Andric       endSymbolRecord(AnnotEnd);
1230044eb2f6SDimitry Andric     }
1231044eb2f6SDimitry Andric 
1232e6d15924SDimitry Andric     for (auto HeapAllocSite : FI.HeapAllocSites) {
1233706b4fc4SDimitry Andric       const MCSymbol *BeginLabel = std::get<0>(HeapAllocSite);
1234706b4fc4SDimitry Andric       const MCSymbol *EndLabel = std::get<1>(HeapAllocSite);
12351d5ae102SDimitry Andric       const DIType *DITy = std::get<2>(HeapAllocSite);
1236e6d15924SDimitry Andric       MCSymbol *HeapAllocEnd = beginSymbolRecord(SymbolKind::S_HEAPALLOCSITE);
1237e6d15924SDimitry Andric       OS.AddComment("Call site offset");
1238145449b1SDimitry Andric       OS.emitCOFFSecRel32(BeginLabel, /*Offset=*/0);
1239e6d15924SDimitry Andric       OS.AddComment("Call site section index");
1240145449b1SDimitry Andric       OS.emitCOFFSectionIndex(BeginLabel);
1241e6d15924SDimitry Andric       OS.AddComment("Call instruction length");
1242e6d15924SDimitry Andric       OS.emitAbsoluteSymbolDiff(EndLabel, BeginLabel, 2);
1243e6d15924SDimitry Andric       OS.AddComment("Type index");
1244cfca06d7SDimitry Andric       OS.emitInt32(getCompleteTypeIndex(DITy).getIndex());
1245e6d15924SDimitry Andric       endSymbolRecord(HeapAllocEnd);
1246e6d15924SDimitry Andric     }
1247e6d15924SDimitry Andric 
124801095a5dSDimitry Andric     if (SP != nullptr)
124901095a5dSDimitry Andric       emitDebugInfoForUDTs(LocalUDTs);
125001095a5dSDimitry Andric 
1251b1c73532SDimitry Andric     emitDebugInfoForJumpTables(FI);
1252b1c73532SDimitry Andric 
125301095a5dSDimitry Andric     // We're done with this function.
1254d8e91e46SDimitry Andric     emitEndSymbolRecord(SymbolKind::S_PROC_ID_END);
125501095a5dSDimitry Andric   }
125601095a5dSDimitry Andric   endCVSubsection(SymbolsEnd);
125701095a5dSDimitry Andric 
125801095a5dSDimitry Andric   // We have an assembler directive that takes care of the whole line table.
1259cfca06d7SDimitry Andric   OS.emitCVLinetableDirective(FI.FuncId, Fn, FI.End);
126001095a5dSDimitry Andric }
126101095a5dSDimitry Andric 
1262145449b1SDimitry Andric CodeViewDebug::LocalVarDef
createDefRangeMem(uint16_t CVRegister,int Offset)126301095a5dSDimitry Andric CodeViewDebug::createDefRangeMem(uint16_t CVRegister, int Offset) {
1264145449b1SDimitry Andric   LocalVarDef DR;
126501095a5dSDimitry Andric   DR.InMemory = -1;
126601095a5dSDimitry Andric   DR.DataOffset = Offset;
126701095a5dSDimitry Andric   assert(DR.DataOffset == Offset && "truncation");
1268b915e9e0SDimitry Andric   DR.IsSubfield = 0;
126901095a5dSDimitry Andric   DR.StructOffset = 0;
127001095a5dSDimitry Andric   DR.CVRegister = CVRegister;
127101095a5dSDimitry Andric   return DR;
127201095a5dSDimitry Andric }
127301095a5dSDimitry Andric 
collectVariableInfoFromMFTable(DenseSet<InlinedEntity> & Processed)1274b915e9e0SDimitry Andric void CodeViewDebug::collectVariableInfoFromMFTable(
1275d8e91e46SDimitry Andric     DenseSet<InlinedEntity> &Processed) {
1276b915e9e0SDimitry Andric   const MachineFunction &MF = *Asm->MF;
1277b915e9e0SDimitry Andric   const TargetSubtargetInfo &TSI = MF.getSubtarget();
127801095a5dSDimitry Andric   const TargetFrameLowering *TFI = TSI.getFrameLowering();
127901095a5dSDimitry Andric   const TargetRegisterInfo *TRI = TSI.getRegisterInfo();
128001095a5dSDimitry Andric 
12817fa27ce4SDimitry Andric   for (const MachineFunction::VariableDbgInfo &VI :
12827fa27ce4SDimitry Andric        MF.getInStackSlotVariableDbgInfo()) {
128301095a5dSDimitry Andric     if (!VI.Var)
128401095a5dSDimitry Andric       continue;
128501095a5dSDimitry Andric     assert(VI.Var->isValidLocationForIntrinsic(VI.Loc) &&
128601095a5dSDimitry Andric            "Expected inlined-at fields to agree");
128701095a5dSDimitry Andric 
1288d8e91e46SDimitry Andric     Processed.insert(InlinedEntity(VI.Var, VI.Loc->getInlinedAt()));
128901095a5dSDimitry Andric     LexicalScope *Scope = LScopes.findLexicalScope(VI.Loc);
129001095a5dSDimitry Andric 
129101095a5dSDimitry Andric     // If variable scope is not found then skip this variable.
129201095a5dSDimitry Andric     if (!Scope)
129301095a5dSDimitry Andric       continue;
129401095a5dSDimitry Andric 
12956b3f41edSDimitry Andric     // If the variable has an attached offset expression, extract it.
12966b3f41edSDimitry Andric     // FIXME: Try to handle DW_OP_deref as well.
12976b3f41edSDimitry Andric     int64_t ExprOffset = 0;
1298e6d15924SDimitry Andric     bool Deref = false;
1299e6d15924SDimitry Andric     if (VI.Expr) {
1300e6d15924SDimitry Andric       // If there is one DW_OP_deref element, use offset of 0 and keep going.
1301e6d15924SDimitry Andric       if (VI.Expr->getNumElements() == 1 &&
1302e6d15924SDimitry Andric           VI.Expr->getElement(0) == llvm::dwarf::DW_OP_deref)
1303e6d15924SDimitry Andric         Deref = true;
1304e6d15924SDimitry Andric       else if (!VI.Expr->extractIfOffset(ExprOffset))
13056b3f41edSDimitry Andric         continue;
1306e6d15924SDimitry Andric     }
13076b3f41edSDimitry Andric 
130801095a5dSDimitry Andric     // Get the frame register used and the offset.
1309cfca06d7SDimitry Andric     Register FrameReg;
13107fa27ce4SDimitry Andric     StackOffset FrameOffset =
13117fa27ce4SDimitry Andric         TFI->getFrameIndexReference(*Asm->MF, VI.getStackSlot(), FrameReg);
131201095a5dSDimitry Andric     uint16_t CVReg = TRI->getCodeViewRegNum(FrameReg);
131301095a5dSDimitry Andric 
1314b60736ecSDimitry Andric     assert(!FrameOffset.getScalable() &&
1315b60736ecSDimitry Andric            "Frame offsets with a scalable component are not supported");
1316b60736ecSDimitry Andric 
131701095a5dSDimitry Andric     // Calculate the label ranges.
1318145449b1SDimitry Andric     LocalVarDef DefRange =
1319b60736ecSDimitry Andric         createDefRangeMem(CVReg, FrameOffset.getFixed() + ExprOffset);
1320e6d15924SDimitry Andric 
1321145449b1SDimitry Andric     LocalVariable Var;
1322145449b1SDimitry Andric     Var.DIVar = VI.Var;
1323145449b1SDimitry Andric 
132401095a5dSDimitry Andric     for (const InsnRange &Range : Scope->getRanges()) {
132501095a5dSDimitry Andric       const MCSymbol *Begin = getLabelBeforeInsn(Range.first);
132601095a5dSDimitry Andric       const MCSymbol *End = getLabelAfterInsn(Range.second);
132701095a5dSDimitry Andric       End = End ? End : Asm->getFunctionEnd();
1328145449b1SDimitry Andric       Var.DefRanges[DefRange].emplace_back(Begin, End);
132901095a5dSDimitry Andric     }
133001095a5dSDimitry Andric 
1331e6d15924SDimitry Andric     if (Deref)
1332e6d15924SDimitry Andric       Var.UseReferenceType = true;
1333e6d15924SDimitry Andric 
1334eb11fae6SDimitry Andric     recordLocalVariable(std::move(Var), Scope);
133501095a5dSDimitry Andric   }
133601095a5dSDimitry Andric }
133701095a5dSDimitry Andric 
canUseReferenceType(const DbgVariableLocation & Loc)1338044eb2f6SDimitry Andric static bool canUseReferenceType(const DbgVariableLocation &Loc) {
1339044eb2f6SDimitry Andric   return !Loc.LoadChain.empty() && Loc.LoadChain.back() == 0;
1340044eb2f6SDimitry Andric }
1341044eb2f6SDimitry Andric 
needsReferenceType(const DbgVariableLocation & Loc)1342044eb2f6SDimitry Andric static bool needsReferenceType(const DbgVariableLocation &Loc) {
1343044eb2f6SDimitry Andric   return Loc.LoadChain.size() == 2 && Loc.LoadChain.back() == 0;
1344044eb2f6SDimitry Andric }
1345044eb2f6SDimitry Andric 
calculateRanges(LocalVariable & Var,const DbgValueHistoryMap::Entries & Entries)1346044eb2f6SDimitry Andric void CodeViewDebug::calculateRanges(
1347e6d15924SDimitry Andric     LocalVariable &Var, const DbgValueHistoryMap::Entries &Entries) {
1348044eb2f6SDimitry Andric   const TargetRegisterInfo *TRI = Asm->MF->getSubtarget().getRegisterInfo();
1349044eb2f6SDimitry Andric 
1350044eb2f6SDimitry Andric   // Calculate the definition ranges.
1351e6d15924SDimitry Andric   for (auto I = Entries.begin(), E = Entries.end(); I != E; ++I) {
1352e6d15924SDimitry Andric     const auto &Entry = *I;
1353e6d15924SDimitry Andric     if (!Entry.isDbgValue())
1354e6d15924SDimitry Andric       continue;
1355e6d15924SDimitry Andric     const MachineInstr *DVInst = Entry.getInstr();
1356044eb2f6SDimitry Andric     assert(DVInst->isDebugValue() && "Invalid History entry");
1357044eb2f6SDimitry Andric     // FIXME: Find a way to represent constant variables, since they are
1358044eb2f6SDimitry Andric     // relatively common.
1359e3b55780SDimitry Andric     std::optional<DbgVariableLocation> Location =
1360044eb2f6SDimitry Andric         DbgVariableLocation::extractFromMachineInstruction(*DVInst);
1361044eb2f6SDimitry Andric     if (!Location)
1362e3b55780SDimitry Andric     {
1363e3b55780SDimitry Andric       // When we don't have a location this is usually because LLVM has
1364e3b55780SDimitry Andric       // transformed it into a constant and we only have an llvm.dbg.value. We
1365e3b55780SDimitry Andric       // can't represent these well in CodeView since S_LOCAL only works on
1366e3b55780SDimitry Andric       // registers and memory locations. Instead, we will pretend this to be a
1367e3b55780SDimitry Andric       // constant value to at least have it show up in the debugger.
1368e3b55780SDimitry Andric       auto Op = DVInst->getDebugOperand(0);
1369e3b55780SDimitry Andric       if (Op.isImm())
1370e3b55780SDimitry Andric         Var.ConstantValue = APSInt(APInt(64, Op.getImm()), false);
1371044eb2f6SDimitry Andric       continue;
1372e3b55780SDimitry Andric     }
1373044eb2f6SDimitry Andric 
1374044eb2f6SDimitry Andric     // CodeView can only express variables in register and variables in memory
1375044eb2f6SDimitry Andric     // at a constant offset from a register. However, for variables passed
1376044eb2f6SDimitry Andric     // indirectly by pointer, it is common for that pointer to be spilled to a
1377044eb2f6SDimitry Andric     // stack location. For the special case of one offseted load followed by a
1378044eb2f6SDimitry Andric     // zero offset load (a pointer spilled to the stack), we change the type of
1379044eb2f6SDimitry Andric     // the local variable from a value type to a reference type. This tricks the
1380044eb2f6SDimitry Andric     // debugger into doing the load for us.
1381044eb2f6SDimitry Andric     if (Var.UseReferenceType) {
1382044eb2f6SDimitry Andric       // We're using a reference type. Drop the last zero offset load.
1383044eb2f6SDimitry Andric       if (canUseReferenceType(*Location))
1384044eb2f6SDimitry Andric         Location->LoadChain.pop_back();
1385044eb2f6SDimitry Andric       else
1386044eb2f6SDimitry Andric         continue;
1387044eb2f6SDimitry Andric     } else if (needsReferenceType(*Location)) {
1388044eb2f6SDimitry Andric       // This location can't be expressed without switching to a reference type.
1389044eb2f6SDimitry Andric       // Start over using that.
1390044eb2f6SDimitry Andric       Var.UseReferenceType = true;
1391044eb2f6SDimitry Andric       Var.DefRanges.clear();
1392e6d15924SDimitry Andric       calculateRanges(Var, Entries);
1393044eb2f6SDimitry Andric       return;
1394044eb2f6SDimitry Andric     }
1395044eb2f6SDimitry Andric 
1396044eb2f6SDimitry Andric     // We can only handle a register or an offseted load of a register.
1397044eb2f6SDimitry Andric     if (Location->Register == 0 || Location->LoadChain.size() > 1)
1398044eb2f6SDimitry Andric       continue;
1399145449b1SDimitry Andric 
1400312c0ed1SDimitry Andric     // Codeview can only express byte-aligned offsets, ensure that we have a
1401312c0ed1SDimitry Andric     // byte-boundaried location.
1402312c0ed1SDimitry Andric     if (Location->FragmentInfo)
1403312c0ed1SDimitry Andric       if (Location->FragmentInfo->OffsetInBits % 8)
1404312c0ed1SDimitry Andric         continue;
1405312c0ed1SDimitry Andric 
1406145449b1SDimitry Andric     LocalVarDef DR;
1407044eb2f6SDimitry Andric     DR.CVRegister = TRI->getCodeViewRegNum(Location->Register);
1408044eb2f6SDimitry Andric     DR.InMemory = !Location->LoadChain.empty();
1409044eb2f6SDimitry Andric     DR.DataOffset =
1410044eb2f6SDimitry Andric         !Location->LoadChain.empty() ? Location->LoadChain.back() : 0;
1411044eb2f6SDimitry Andric     if (Location->FragmentInfo) {
1412044eb2f6SDimitry Andric       DR.IsSubfield = true;
1413044eb2f6SDimitry Andric       DR.StructOffset = Location->FragmentInfo->OffsetInBits / 8;
1414044eb2f6SDimitry Andric     } else {
1415044eb2f6SDimitry Andric       DR.IsSubfield = false;
1416044eb2f6SDimitry Andric       DR.StructOffset = 0;
1417044eb2f6SDimitry Andric     }
1418044eb2f6SDimitry Andric 
1419044eb2f6SDimitry Andric     // Compute the label range.
1420e6d15924SDimitry Andric     const MCSymbol *Begin = getLabelBeforeInsn(Entry.getInstr());
1421e6d15924SDimitry Andric     const MCSymbol *End;
1422e6d15924SDimitry Andric     if (Entry.getEndIndex() != DbgValueHistoryMap::NoEntry) {
1423e6d15924SDimitry Andric       auto &EndingEntry = Entries[Entry.getEndIndex()];
1424e6d15924SDimitry Andric       End = EndingEntry.isDbgValue()
1425e6d15924SDimitry Andric                 ? getLabelBeforeInsn(EndingEntry.getInstr())
1426e6d15924SDimitry Andric                 : getLabelAfterInsn(EndingEntry.getInstr());
1427e6d15924SDimitry Andric     } else
1428044eb2f6SDimitry Andric       End = Asm->getFunctionEnd();
1429044eb2f6SDimitry Andric 
1430044eb2f6SDimitry Andric     // If the last range end is our begin, just extend the last range.
1431044eb2f6SDimitry Andric     // Otherwise make a new range.
1432044eb2f6SDimitry Andric     SmallVectorImpl<std::pair<const MCSymbol *, const MCSymbol *>> &R =
1433145449b1SDimitry Andric         Var.DefRanges[DR];
1434044eb2f6SDimitry Andric     if (!R.empty() && R.back().second == Begin)
1435044eb2f6SDimitry Andric       R.back().second = End;
1436044eb2f6SDimitry Andric     else
1437044eb2f6SDimitry Andric       R.emplace_back(Begin, End);
1438044eb2f6SDimitry Andric 
1439044eb2f6SDimitry Andric     // FIXME: Do more range combining.
1440044eb2f6SDimitry Andric   }
1441044eb2f6SDimitry Andric }
1442044eb2f6SDimitry Andric 
collectVariableInfo(const DISubprogram * SP)144301095a5dSDimitry Andric void CodeViewDebug::collectVariableInfo(const DISubprogram *SP) {
1444d8e91e46SDimitry Andric   DenseSet<InlinedEntity> Processed;
144501095a5dSDimitry Andric   // Grab the variable info that was squirreled away in the MMI side-table.
1446b915e9e0SDimitry Andric   collectVariableInfoFromMFTable(Processed);
144701095a5dSDimitry Andric 
144801095a5dSDimitry Andric   for (const auto &I : DbgValues) {
1449d8e91e46SDimitry Andric     InlinedEntity IV = I.first;
145001095a5dSDimitry Andric     if (Processed.count(IV))
145101095a5dSDimitry Andric       continue;
1452d8e91e46SDimitry Andric     const DILocalVariable *DIVar = cast<DILocalVariable>(IV.first);
145301095a5dSDimitry Andric     const DILocation *InlinedAt = IV.second;
145401095a5dSDimitry Andric 
145501095a5dSDimitry Andric     // Instruction ranges, specifying where IV is accessible.
1456e6d15924SDimitry Andric     const auto &Entries = I.second;
145701095a5dSDimitry Andric 
145801095a5dSDimitry Andric     LexicalScope *Scope = nullptr;
145901095a5dSDimitry Andric     if (InlinedAt)
146001095a5dSDimitry Andric       Scope = LScopes.findInlinedScope(DIVar->getScope(), InlinedAt);
146101095a5dSDimitry Andric     else
146201095a5dSDimitry Andric       Scope = LScopes.findLexicalScope(DIVar->getScope());
146301095a5dSDimitry Andric     // If variable scope is not found then skip this variable.
146401095a5dSDimitry Andric     if (!Scope)
146501095a5dSDimitry Andric       continue;
146601095a5dSDimitry Andric 
146701095a5dSDimitry Andric     LocalVariable Var;
146801095a5dSDimitry Andric     Var.DIVar = DIVar;
146901095a5dSDimitry Andric 
1470e6d15924SDimitry Andric     calculateRanges(Var, Entries);
1471eb11fae6SDimitry Andric     recordLocalVariable(std::move(Var), Scope);
147201095a5dSDimitry Andric   }
147301095a5dSDimitry Andric }
147401095a5dSDimitry Andric 
beginFunctionImpl(const MachineFunction * MF)147571d5a254SDimitry Andric void CodeViewDebug::beginFunctionImpl(const MachineFunction *MF) {
1476d8e91e46SDimitry Andric   const TargetSubtargetInfo &TSI = MF->getSubtarget();
1477d8e91e46SDimitry Andric   const TargetRegisterInfo *TRI = TSI.getRegisterInfo();
1478d8e91e46SDimitry Andric   const MachineFrameInfo &MFI = MF->getFrameInfo();
1479044eb2f6SDimitry Andric   const Function &GV = MF->getFunction();
14801d5ae102SDimitry Andric   auto Insertion = FnDebugInfo.insert({&GV, std::make_unique<FunctionInfo>()});
1481eb11fae6SDimitry Andric   assert(Insertion.second && "function already has info");
1482eb11fae6SDimitry Andric   CurFn = Insertion.first->second.get();
148301095a5dSDimitry Andric   CurFn->FuncId = NextFuncId++;
148401095a5dSDimitry Andric   CurFn->Begin = Asm->getFunctionBegin();
148501095a5dSDimitry Andric 
1486d8e91e46SDimitry Andric   // The S_FRAMEPROC record reports the stack size, and how many bytes of
1487d8e91e46SDimitry Andric   // callee-saved registers were used. For targets that don't use a PUSH
1488d8e91e46SDimitry Andric   // instruction (AArch64), this will be zero.
1489d8e91e46SDimitry Andric   CurFn->CSRSize = MFI.getCVBytesOfCalleeSavedRegisters();
1490d8e91e46SDimitry Andric   CurFn->FrameSize = MFI.getStackSize();
1491d8e91e46SDimitry Andric   CurFn->OffsetAdjustment = MFI.getOffsetAdjustment();
1492344a3780SDimitry Andric   CurFn->HasStackRealignment = TRI->hasStackRealignment(*MF);
1493d8e91e46SDimitry Andric 
1494d8e91e46SDimitry Andric   // For this function S_FRAMEPROC record, figure out which codeview register
1495d8e91e46SDimitry Andric   // will be the frame pointer.
1496d8e91e46SDimitry Andric   CurFn->EncodedParamFramePtrReg = EncodedFramePtrReg::None; // None.
1497d8e91e46SDimitry Andric   CurFn->EncodedLocalFramePtrReg = EncodedFramePtrReg::None; // None.
1498d8e91e46SDimitry Andric   if (CurFn->FrameSize > 0) {
1499d8e91e46SDimitry Andric     if (!TSI.getFrameLowering()->hasFP(*MF)) {
1500d8e91e46SDimitry Andric       CurFn->EncodedLocalFramePtrReg = EncodedFramePtrReg::StackPtr;
1501d8e91e46SDimitry Andric       CurFn->EncodedParamFramePtrReg = EncodedFramePtrReg::StackPtr;
1502d8e91e46SDimitry Andric     } else {
15037fa27ce4SDimitry Andric       CurFn->HasFramePointer = true;
1504d8e91e46SDimitry Andric       // If there is an FP, parameters are always relative to it.
1505d8e91e46SDimitry Andric       CurFn->EncodedParamFramePtrReg = EncodedFramePtrReg::FramePtr;
1506d8e91e46SDimitry Andric       if (CurFn->HasStackRealignment) {
1507d8e91e46SDimitry Andric         // If the stack needs realignment, locals are relative to SP or VFRAME.
1508d8e91e46SDimitry Andric         CurFn->EncodedLocalFramePtrReg = EncodedFramePtrReg::StackPtr;
1509d8e91e46SDimitry Andric       } else {
1510d8e91e46SDimitry Andric         // Otherwise, locals are relative to EBP, and we probably have VLAs or
1511d8e91e46SDimitry Andric         // other stack adjustments.
1512d8e91e46SDimitry Andric         CurFn->EncodedLocalFramePtrReg = EncodedFramePtrReg::FramePtr;
1513d8e91e46SDimitry Andric       }
1514d8e91e46SDimitry Andric     }
1515d8e91e46SDimitry Andric   }
1516d8e91e46SDimitry Andric 
1517d8e91e46SDimitry Andric   // Compute other frame procedure options.
1518d8e91e46SDimitry Andric   FrameProcedureOptions FPO = FrameProcedureOptions::None;
1519d8e91e46SDimitry Andric   if (MFI.hasVarSizedObjects())
1520d8e91e46SDimitry Andric     FPO |= FrameProcedureOptions::HasAlloca;
1521d8e91e46SDimitry Andric   if (MF->exposesReturnsTwice())
1522d8e91e46SDimitry Andric     FPO |= FrameProcedureOptions::HasSetJmp;
1523d8e91e46SDimitry Andric   // FIXME: Set HasLongJmp if we ever track that info.
1524d8e91e46SDimitry Andric   if (MF->hasInlineAsm())
1525d8e91e46SDimitry Andric     FPO |= FrameProcedureOptions::HasInlineAssembly;
1526d8e91e46SDimitry Andric   if (GV.hasPersonalityFn()) {
1527d8e91e46SDimitry Andric     if (isAsynchronousEHPersonality(
1528d8e91e46SDimitry Andric             classifyEHPersonality(GV.getPersonalityFn())))
1529d8e91e46SDimitry Andric       FPO |= FrameProcedureOptions::HasStructuredExceptionHandling;
1530d8e91e46SDimitry Andric     else
1531d8e91e46SDimitry Andric       FPO |= FrameProcedureOptions::HasExceptionHandling;
1532d8e91e46SDimitry Andric   }
1533d8e91e46SDimitry Andric   if (GV.hasFnAttribute(Attribute::InlineHint))
1534d8e91e46SDimitry Andric     FPO |= FrameProcedureOptions::MarkedInline;
1535d8e91e46SDimitry Andric   if (GV.hasFnAttribute(Attribute::Naked))
1536d8e91e46SDimitry Andric     FPO |= FrameProcedureOptions::Naked;
1537e3b55780SDimitry Andric   if (MFI.hasStackProtectorIndex()) {
1538d8e91e46SDimitry Andric     FPO |= FrameProcedureOptions::SecurityChecks;
1539e3b55780SDimitry Andric     if (GV.hasFnAttribute(Attribute::StackProtectStrong) ||
1540e3b55780SDimitry Andric         GV.hasFnAttribute(Attribute::StackProtectReq)) {
1541e3b55780SDimitry Andric       FPO |= FrameProcedureOptions::StrictSecurityChecks;
1542e3b55780SDimitry Andric     }
1543e3b55780SDimitry Andric   } else if (!GV.hasStackProtectorFnAttr()) {
1544e3b55780SDimitry Andric     // __declspec(safebuffers) disables stack guards.
1545e3b55780SDimitry Andric     FPO |= FrameProcedureOptions::SafeBuffers;
1546e3b55780SDimitry Andric   }
1547d8e91e46SDimitry Andric   FPO |= FrameProcedureOptions(uint32_t(CurFn->EncodedLocalFramePtrReg) << 14U);
1548d8e91e46SDimitry Andric   FPO |= FrameProcedureOptions(uint32_t(CurFn->EncodedParamFramePtrReg) << 16U);
1549b1c73532SDimitry Andric   if (Asm->TM.getOptLevel() != CodeGenOptLevel::None && !GV.hasOptSize() &&
1550b1c73532SDimitry Andric       !GV.hasOptNone())
1551d8e91e46SDimitry Andric     FPO |= FrameProcedureOptions::OptimizedForSpeed;
1552344a3780SDimitry Andric   if (GV.hasProfileData()) {
1553344a3780SDimitry Andric     FPO |= FrameProcedureOptions::ValidProfileCounts;
1554344a3780SDimitry Andric     FPO |= FrameProcedureOptions::ProfileGuidedOptimization;
1555344a3780SDimitry Andric   }
1556d8e91e46SDimitry Andric   // FIXME: Set GuardCfg when it is implemented.
1557d8e91e46SDimitry Andric   CurFn->FrameProcOpts = FPO;
1558d8e91e46SDimitry Andric 
1559145449b1SDimitry Andric   OS.emitCVFuncIdDirective(CurFn->FuncId);
1560b915e9e0SDimitry Andric 
156101095a5dSDimitry Andric   // Find the end of the function prolog.  First known non-DBG_VALUE and
156201095a5dSDimitry Andric   // non-frame setup location marks the beginning of the function body.
156301095a5dSDimitry Andric   // FIXME: is there a simpler a way to do this? Can we just search
156401095a5dSDimitry Andric   // for the first instruction of the function, not the last of the prolog?
156501095a5dSDimitry Andric   DebugLoc PrologEndLoc;
156601095a5dSDimitry Andric   bool EmptyPrologue = true;
156701095a5dSDimitry Andric   for (const auto &MBB : *MF) {
156801095a5dSDimitry Andric     for (const auto &MI : MBB) {
1569ab44ce3dSDimitry Andric       if (!MI.isMetaInstruction() && !MI.getFlag(MachineInstr::FrameSetup) &&
157001095a5dSDimitry Andric           MI.getDebugLoc()) {
157101095a5dSDimitry Andric         PrologEndLoc = MI.getDebugLoc();
157201095a5dSDimitry Andric         break;
1573ab44ce3dSDimitry Andric       } else if (!MI.isMetaInstruction()) {
157401095a5dSDimitry Andric         EmptyPrologue = false;
157501095a5dSDimitry Andric       }
157601095a5dSDimitry Andric     }
157701095a5dSDimitry Andric   }
157801095a5dSDimitry Andric 
157901095a5dSDimitry Andric   // Record beginning of function if we have a non-empty prologue.
158001095a5dSDimitry Andric   if (PrologEndLoc && !EmptyPrologue) {
158101095a5dSDimitry Andric     DebugLoc FnStartDL = PrologEndLoc.getFnDebugLoc();
158201095a5dSDimitry Andric     maybeRecordLocation(FnStartDL, MF);
158301095a5dSDimitry Andric   }
1584706b4fc4SDimitry Andric 
1585706b4fc4SDimitry Andric   // Find heap alloc sites and emit labels around them.
1586706b4fc4SDimitry Andric   for (const auto &MBB : *MF) {
1587706b4fc4SDimitry Andric     for (const auto &MI : MBB) {
1588706b4fc4SDimitry Andric       if (MI.getHeapAllocMarker()) {
1589706b4fc4SDimitry Andric         requestLabelBeforeInsn(&MI);
1590706b4fc4SDimitry Andric         requestLabelAfterInsn(&MI);
1591706b4fc4SDimitry Andric       }
1592706b4fc4SDimitry Andric     }
1593706b4fc4SDimitry Andric   }
1594b1c73532SDimitry Andric 
1595b1c73532SDimitry Andric   // Mark branches that may potentially be using jump tables with labels.
1596b1c73532SDimitry Andric   bool isThumb = Triple(MMI->getModule()->getTargetTriple()).getArch() ==
1597b1c73532SDimitry Andric                  llvm::Triple::ArchType::thumb;
1598b1c73532SDimitry Andric   discoverJumpTableBranches(MF, isThumb);
159901095a5dSDimitry Andric }
160001095a5dSDimitry Andric 
shouldEmitUdt(const DIType * T)1601044eb2f6SDimitry Andric static bool shouldEmitUdt(const DIType *T) {
1602044eb2f6SDimitry Andric   if (!T)
1603044eb2f6SDimitry Andric     return false;
1604044eb2f6SDimitry Andric 
1605044eb2f6SDimitry Andric   // MSVC does not emit UDTs for typedefs that are scoped to classes.
1606044eb2f6SDimitry Andric   if (T->getTag() == dwarf::DW_TAG_typedef) {
1607e6d15924SDimitry Andric     if (DIScope *Scope = T->getScope()) {
1608044eb2f6SDimitry Andric       switch (Scope->getTag()) {
1609044eb2f6SDimitry Andric       case dwarf::DW_TAG_structure_type:
1610044eb2f6SDimitry Andric       case dwarf::DW_TAG_class_type:
1611044eb2f6SDimitry Andric       case dwarf::DW_TAG_union_type:
1612044eb2f6SDimitry Andric         return false;
1613344a3780SDimitry Andric       default:
1614344a3780SDimitry Andric           // do nothing.
1615344a3780SDimitry Andric           ;
1616044eb2f6SDimitry Andric       }
1617044eb2f6SDimitry Andric     }
1618044eb2f6SDimitry Andric   }
1619044eb2f6SDimitry Andric 
1620044eb2f6SDimitry Andric   while (true) {
1621044eb2f6SDimitry Andric     if (!T || T->isForwardDecl())
1622044eb2f6SDimitry Andric       return false;
1623044eb2f6SDimitry Andric 
1624044eb2f6SDimitry Andric     const DIDerivedType *DT = dyn_cast<DIDerivedType>(T);
1625044eb2f6SDimitry Andric     if (!DT)
1626044eb2f6SDimitry Andric       return true;
1627e6d15924SDimitry Andric     T = DT->getBaseType();
1628044eb2f6SDimitry Andric   }
1629044eb2f6SDimitry Andric   return true;
1630044eb2f6SDimitry Andric }
1631044eb2f6SDimitry Andric 
addToUDTs(const DIType * Ty)1632044eb2f6SDimitry Andric void CodeViewDebug::addToUDTs(const DIType *Ty) {
163301095a5dSDimitry Andric   // Don't record empty UDTs.
163401095a5dSDimitry Andric   if (Ty->getName().empty())
163501095a5dSDimitry Andric     return;
1636044eb2f6SDimitry Andric   if (!shouldEmitUdt(Ty))
1637044eb2f6SDimitry Andric     return;
163801095a5dSDimitry Andric 
1639cfca06d7SDimitry Andric   SmallVector<StringRef, 5> ParentScopeNames;
1640e6d15924SDimitry Andric   const DISubprogram *ClosestSubprogram =
1641cfca06d7SDimitry Andric       collectParentScopeNames(Ty->getScope(), ParentScopeNames);
164201095a5dSDimitry Andric 
164301095a5dSDimitry Andric   std::string FullyQualifiedName =
1644cfca06d7SDimitry Andric       formatNestedName(ParentScopeNames, getPrettyScopeName(Ty));
164501095a5dSDimitry Andric 
1646044eb2f6SDimitry Andric   if (ClosestSubprogram == nullptr) {
1647044eb2f6SDimitry Andric     GlobalUDTs.emplace_back(std::move(FullyQualifiedName), Ty);
1648044eb2f6SDimitry Andric   } else if (ClosestSubprogram == CurrentSubprogram) {
1649044eb2f6SDimitry Andric     LocalUDTs.emplace_back(std::move(FullyQualifiedName), Ty);
1650044eb2f6SDimitry Andric   }
165101095a5dSDimitry Andric 
165201095a5dSDimitry Andric   // TODO: What if the ClosestSubprogram is neither null or the current
165301095a5dSDimitry Andric   // subprogram?  Currently, the UDT just gets dropped on the floor.
165401095a5dSDimitry Andric   //
165501095a5dSDimitry Andric   // The current behavior is not desirable.  To get maximal fidelity, we would
165601095a5dSDimitry Andric   // need to perform all type translation before beginning emission of .debug$S
165701095a5dSDimitry Andric   // and then make LocalUDTs a member of FunctionInfo
165801095a5dSDimitry Andric }
165901095a5dSDimitry Andric 
lowerType(const DIType * Ty,const DIType * ClassTy)166001095a5dSDimitry Andric TypeIndex CodeViewDebug::lowerType(const DIType *Ty, const DIType *ClassTy) {
166101095a5dSDimitry Andric   // Generic dispatch for lowering an unknown type.
166201095a5dSDimitry Andric   switch (Ty->getTag()) {
166301095a5dSDimitry Andric   case dwarf::DW_TAG_array_type:
166401095a5dSDimitry Andric     return lowerTypeArray(cast<DICompositeType>(Ty));
166501095a5dSDimitry Andric   case dwarf::DW_TAG_typedef:
166601095a5dSDimitry Andric     return lowerTypeAlias(cast<DIDerivedType>(Ty));
166701095a5dSDimitry Andric   case dwarf::DW_TAG_base_type:
166801095a5dSDimitry Andric     return lowerTypeBasic(cast<DIBasicType>(Ty));
166901095a5dSDimitry Andric   case dwarf::DW_TAG_pointer_type:
1670b915e9e0SDimitry Andric     if (cast<DIDerivedType>(Ty)->getName() == "__vtbl_ptr_type")
1671b915e9e0SDimitry Andric       return lowerTypeVFTableShape(cast<DIDerivedType>(Ty));
1672e3b55780SDimitry Andric     [[fallthrough]];
167301095a5dSDimitry Andric   case dwarf::DW_TAG_reference_type:
167401095a5dSDimitry Andric   case dwarf::DW_TAG_rvalue_reference_type:
167501095a5dSDimitry Andric     return lowerTypePointer(cast<DIDerivedType>(Ty));
167601095a5dSDimitry Andric   case dwarf::DW_TAG_ptr_to_member_type:
167701095a5dSDimitry Andric     return lowerTypeMemberPointer(cast<DIDerivedType>(Ty));
1678eb11fae6SDimitry Andric   case dwarf::DW_TAG_restrict_type:
167901095a5dSDimitry Andric   case dwarf::DW_TAG_const_type:
168001095a5dSDimitry Andric   case dwarf::DW_TAG_volatile_type:
1681b915e9e0SDimitry Andric   // TODO: add support for DW_TAG_atomic_type here
168201095a5dSDimitry Andric     return lowerTypeModifier(cast<DIDerivedType>(Ty));
168301095a5dSDimitry Andric   case dwarf::DW_TAG_subroutine_type:
168401095a5dSDimitry Andric     if (ClassTy) {
168501095a5dSDimitry Andric       // The member function type of a member function pointer has no
168601095a5dSDimitry Andric       // ThisAdjustment.
168701095a5dSDimitry Andric       return lowerTypeMemberFunction(cast<DISubroutineType>(Ty), ClassTy,
1688044eb2f6SDimitry Andric                                      /*ThisAdjustment=*/0,
1689044eb2f6SDimitry Andric                                      /*IsStaticMethod=*/false);
169001095a5dSDimitry Andric     }
169101095a5dSDimitry Andric     return lowerTypeFunction(cast<DISubroutineType>(Ty));
169201095a5dSDimitry Andric   case dwarf::DW_TAG_enumeration_type:
169301095a5dSDimitry Andric     return lowerTypeEnum(cast<DICompositeType>(Ty));
169401095a5dSDimitry Andric   case dwarf::DW_TAG_class_type:
169501095a5dSDimitry Andric   case dwarf::DW_TAG_structure_type:
169601095a5dSDimitry Andric     return lowerTypeClass(cast<DICompositeType>(Ty));
169701095a5dSDimitry Andric   case dwarf::DW_TAG_union_type:
169801095a5dSDimitry Andric     return lowerTypeUnion(cast<DICompositeType>(Ty));
1699c0981da4SDimitry Andric   case dwarf::DW_TAG_string_type:
1700c0981da4SDimitry Andric     return lowerTypeString(cast<DIStringType>(Ty));
1701eb11fae6SDimitry Andric   case dwarf::DW_TAG_unspecified_type:
1702d8e91e46SDimitry Andric     if (Ty->getName() == "decltype(nullptr)")
1703d8e91e46SDimitry Andric       return TypeIndex::NullptrT();
1704eb11fae6SDimitry Andric     return TypeIndex::None();
170501095a5dSDimitry Andric   default:
170601095a5dSDimitry Andric     // Use the null type index.
170701095a5dSDimitry Andric     return TypeIndex();
170801095a5dSDimitry Andric   }
170901095a5dSDimitry Andric }
171001095a5dSDimitry Andric 
lowerTypeAlias(const DIDerivedType * Ty)171101095a5dSDimitry Andric TypeIndex CodeViewDebug::lowerTypeAlias(const DIDerivedType *Ty) {
1712e6d15924SDimitry Andric   TypeIndex UnderlyingTypeIndex = getTypeIndex(Ty->getBaseType());
171301095a5dSDimitry Andric   StringRef TypeName = Ty->getName();
171401095a5dSDimitry Andric 
1715044eb2f6SDimitry Andric   addToUDTs(Ty);
171601095a5dSDimitry Andric 
171701095a5dSDimitry Andric   if (UnderlyingTypeIndex == TypeIndex(SimpleTypeKind::Int32Long) &&
171801095a5dSDimitry Andric       TypeName == "HRESULT")
171901095a5dSDimitry Andric     return TypeIndex(SimpleTypeKind::HResult);
172001095a5dSDimitry Andric   if (UnderlyingTypeIndex == TypeIndex(SimpleTypeKind::UInt16Short) &&
172101095a5dSDimitry Andric       TypeName == "wchar_t")
172201095a5dSDimitry Andric     return TypeIndex(SimpleTypeKind::WideCharacter);
172301095a5dSDimitry Andric 
172401095a5dSDimitry Andric   return UnderlyingTypeIndex;
172501095a5dSDimitry Andric }
172601095a5dSDimitry Andric 
lowerTypeArray(const DICompositeType * Ty)172701095a5dSDimitry Andric TypeIndex CodeViewDebug::lowerTypeArray(const DICompositeType *Ty) {
1728e6d15924SDimitry Andric   const DIType *ElementType = Ty->getBaseType();
1729e6d15924SDimitry Andric   TypeIndex ElementTypeIndex = getTypeIndex(ElementType);
173001095a5dSDimitry Andric   // IndexType is size_t, which depends on the bitness of the target.
1731eb11fae6SDimitry Andric   TypeIndex IndexType = getPointerSizeInBytes() == 8
173201095a5dSDimitry Andric                             ? TypeIndex(SimpleTypeKind::UInt64Quad)
173301095a5dSDimitry Andric                             : TypeIndex(SimpleTypeKind::UInt32Long);
173401095a5dSDimitry Andric 
1735e6d15924SDimitry Andric   uint64_t ElementSize = getBaseTypeSize(ElementType) / 8;
173601095a5dSDimitry Andric 
173701095a5dSDimitry Andric   // Add subranges to array type.
173801095a5dSDimitry Andric   DINodeArray Elements = Ty->getElements();
173901095a5dSDimitry Andric   for (int i = Elements.size() - 1; i >= 0; --i) {
174001095a5dSDimitry Andric     const DINode *Element = Elements[i];
174101095a5dSDimitry Andric     assert(Element->getTag() == dwarf::DW_TAG_subrange_type);
174201095a5dSDimitry Andric 
174301095a5dSDimitry Andric     const DISubrange *Subrange = cast<DISubrange>(Element);
1744eb11fae6SDimitry Andric     int64_t Count = -1;
1745c0981da4SDimitry Andric 
1746c0981da4SDimitry Andric     // If Subrange has a Count field, use it.
1747c0981da4SDimitry Andric     // Otherwise, if it has an upperboud, use (upperbound - lowerbound + 1),
1748c0981da4SDimitry Andric     // where lowerbound is from the LowerBound field of the Subrange,
1749c0981da4SDimitry Andric     // or the language default lowerbound if that field is unspecified.
17507fa27ce4SDimitry Andric     if (auto *CI = dyn_cast_if_present<ConstantInt *>(Subrange->getCount()))
1751eb11fae6SDimitry Andric       Count = CI->getSExtValue();
17527fa27ce4SDimitry Andric     else if (auto *UI = dyn_cast_if_present<ConstantInt *>(
17537fa27ce4SDimitry Andric                  Subrange->getUpperBound())) {
1754c0981da4SDimitry Andric       // Fortran uses 1 as the default lowerbound; other languages use 0.
1755c0981da4SDimitry Andric       int64_t Lowerbound = (moduleIsInFortran()) ? 1 : 0;
17567fa27ce4SDimitry Andric       auto *LI = dyn_cast_if_present<ConstantInt *>(Subrange->getLowerBound());
1757c0981da4SDimitry Andric       Lowerbound = (LI) ? LI->getSExtValue() : Lowerbound;
1758c0981da4SDimitry Andric       Count = UI->getSExtValue() - Lowerbound + 1;
1759b60736ecSDimitry Andric     }
176001095a5dSDimitry Andric 
1761044eb2f6SDimitry Andric     // Forward declarations of arrays without a size and VLAs use a count of -1.
1762044eb2f6SDimitry Andric     // Emit a count of zero in these cases to match what MSVC does for arrays
1763044eb2f6SDimitry Andric     // without a size. MSVC doesn't support VLAs, so it's not clear what we
1764044eb2f6SDimitry Andric     // should do for them even if we could distinguish them.
176571d5a254SDimitry Andric     if (Count == -1)
1766044eb2f6SDimitry Andric       Count = 0;
176701095a5dSDimitry Andric 
176801095a5dSDimitry Andric     // Update the element size and element type index for subsequent subranges.
176901095a5dSDimitry Andric     ElementSize *= Count;
1770b915e9e0SDimitry Andric 
1771b915e9e0SDimitry Andric     // If this is the outermost array, use the size from the array. It will be
177271d5a254SDimitry Andric     // more accurate if we had a VLA or an incomplete element type size.
1773b915e9e0SDimitry Andric     uint64_t ArraySize =
1774b915e9e0SDimitry Andric         (i == 0 && ElementSize == 0) ? Ty->getSizeInBits() / 8 : ElementSize;
1775b915e9e0SDimitry Andric 
1776b915e9e0SDimitry Andric     StringRef Name = (i == 0) ? Ty->getName() : "";
1777b915e9e0SDimitry Andric     ArrayRecord AR(ElementTypeIndex, IndexType, ArraySize, Name);
1778044eb2f6SDimitry Andric     ElementTypeIndex = TypeTable.writeLeafType(AR);
177901095a5dSDimitry Andric   }
178001095a5dSDimitry Andric 
178101095a5dSDimitry Andric   return ElementTypeIndex;
178201095a5dSDimitry Andric }
178301095a5dSDimitry Andric 
1784c0981da4SDimitry Andric // This function lowers a Fortran character type (DIStringType).
1785c0981da4SDimitry Andric // Note that it handles only the character*n variant (using SizeInBits
1786c0981da4SDimitry Andric // field in DIString to describe the type size) at the moment.
1787c0981da4SDimitry Andric // Other variants (leveraging the StringLength and StringLengthExp
1788c0981da4SDimitry Andric // fields in DIStringType) remain TBD.
lowerTypeString(const DIStringType * Ty)1789c0981da4SDimitry Andric TypeIndex CodeViewDebug::lowerTypeString(const DIStringType *Ty) {
1790c0981da4SDimitry Andric   TypeIndex CharType = TypeIndex(SimpleTypeKind::NarrowCharacter);
1791c0981da4SDimitry Andric   uint64_t ArraySize = Ty->getSizeInBits() >> 3;
1792c0981da4SDimitry Andric   StringRef Name = Ty->getName();
1793c0981da4SDimitry Andric   // IndexType is size_t, which depends on the bitness of the target.
1794c0981da4SDimitry Andric   TypeIndex IndexType = getPointerSizeInBytes() == 8
1795c0981da4SDimitry Andric                             ? TypeIndex(SimpleTypeKind::UInt64Quad)
1796c0981da4SDimitry Andric                             : TypeIndex(SimpleTypeKind::UInt32Long);
1797c0981da4SDimitry Andric 
1798c0981da4SDimitry Andric   // Create a type of character array of ArraySize.
1799c0981da4SDimitry Andric   ArrayRecord AR(CharType, IndexType, ArraySize, Name);
1800c0981da4SDimitry Andric 
1801c0981da4SDimitry Andric   return TypeTable.writeLeafType(AR);
1802c0981da4SDimitry Andric }
1803c0981da4SDimitry Andric 
lowerTypeBasic(const DIBasicType * Ty)180401095a5dSDimitry Andric TypeIndex CodeViewDebug::lowerTypeBasic(const DIBasicType *Ty) {
180501095a5dSDimitry Andric   TypeIndex Index;
180601095a5dSDimitry Andric   dwarf::TypeKind Kind;
180701095a5dSDimitry Andric   uint32_t ByteSize;
180801095a5dSDimitry Andric 
180901095a5dSDimitry Andric   Kind = static_cast<dwarf::TypeKind>(Ty->getEncoding());
181001095a5dSDimitry Andric   ByteSize = Ty->getSizeInBits() / 8;
181101095a5dSDimitry Andric 
181201095a5dSDimitry Andric   SimpleTypeKind STK = SimpleTypeKind::None;
181301095a5dSDimitry Andric   switch (Kind) {
181401095a5dSDimitry Andric   case dwarf::DW_ATE_address:
181501095a5dSDimitry Andric     // FIXME: Translate
181601095a5dSDimitry Andric     break;
181701095a5dSDimitry Andric   case dwarf::DW_ATE_boolean:
181801095a5dSDimitry Andric     switch (ByteSize) {
181901095a5dSDimitry Andric     case 1:  STK = SimpleTypeKind::Boolean8;   break;
182001095a5dSDimitry Andric     case 2:  STK = SimpleTypeKind::Boolean16;  break;
182101095a5dSDimitry Andric     case 4:  STK = SimpleTypeKind::Boolean32;  break;
182201095a5dSDimitry Andric     case 8:  STK = SimpleTypeKind::Boolean64;  break;
182301095a5dSDimitry Andric     case 16: STK = SimpleTypeKind::Boolean128; break;
182401095a5dSDimitry Andric     }
182501095a5dSDimitry Andric     break;
182601095a5dSDimitry Andric   case dwarf::DW_ATE_complex_float:
18277fa27ce4SDimitry Andric     // The CodeView size for a complex represents the size of
18287fa27ce4SDimitry Andric     // an individual component.
182901095a5dSDimitry Andric     switch (ByteSize) {
18307fa27ce4SDimitry Andric     case 4:  STK = SimpleTypeKind::Complex16;  break;
18317fa27ce4SDimitry Andric     case 8:  STK = SimpleTypeKind::Complex32;  break;
18327fa27ce4SDimitry Andric     case 16: STK = SimpleTypeKind::Complex64;  break;
18337fa27ce4SDimitry Andric     case 20: STK = SimpleTypeKind::Complex80;  break;
18347fa27ce4SDimitry Andric     case 32: STK = SimpleTypeKind::Complex128; break;
183501095a5dSDimitry Andric     }
183601095a5dSDimitry Andric     break;
183701095a5dSDimitry Andric   case dwarf::DW_ATE_float:
183801095a5dSDimitry Andric     switch (ByteSize) {
183901095a5dSDimitry Andric     case 2:  STK = SimpleTypeKind::Float16;  break;
184001095a5dSDimitry Andric     case 4:  STK = SimpleTypeKind::Float32;  break;
184101095a5dSDimitry Andric     case 6:  STK = SimpleTypeKind::Float48;  break;
184201095a5dSDimitry Andric     case 8:  STK = SimpleTypeKind::Float64;  break;
184301095a5dSDimitry Andric     case 10: STK = SimpleTypeKind::Float80;  break;
184401095a5dSDimitry Andric     case 16: STK = SimpleTypeKind::Float128; break;
184501095a5dSDimitry Andric     }
184601095a5dSDimitry Andric     break;
184701095a5dSDimitry Andric   case dwarf::DW_ATE_signed:
184801095a5dSDimitry Andric     switch (ByteSize) {
1849b915e9e0SDimitry Andric     case 1:  STK = SimpleTypeKind::SignedCharacter; break;
185001095a5dSDimitry Andric     case 2:  STK = SimpleTypeKind::Int16Short;      break;
185101095a5dSDimitry Andric     case 4:  STK = SimpleTypeKind::Int32;           break;
185201095a5dSDimitry Andric     case 8:  STK = SimpleTypeKind::Int64Quad;       break;
185301095a5dSDimitry Andric     case 16: STK = SimpleTypeKind::Int128Oct;       break;
185401095a5dSDimitry Andric     }
185501095a5dSDimitry Andric     break;
185601095a5dSDimitry Andric   case dwarf::DW_ATE_unsigned:
185701095a5dSDimitry Andric     switch (ByteSize) {
1858b915e9e0SDimitry Andric     case 1:  STK = SimpleTypeKind::UnsignedCharacter; break;
185901095a5dSDimitry Andric     case 2:  STK = SimpleTypeKind::UInt16Short;       break;
186001095a5dSDimitry Andric     case 4:  STK = SimpleTypeKind::UInt32;            break;
186101095a5dSDimitry Andric     case 8:  STK = SimpleTypeKind::UInt64Quad;        break;
186201095a5dSDimitry Andric     case 16: STK = SimpleTypeKind::UInt128Oct;        break;
186301095a5dSDimitry Andric     }
186401095a5dSDimitry Andric     break;
186501095a5dSDimitry Andric   case dwarf::DW_ATE_UTF:
186601095a5dSDimitry Andric     switch (ByteSize) {
1867145449b1SDimitry Andric     case 1: STK = SimpleTypeKind::Character8; break;
186801095a5dSDimitry Andric     case 2: STK = SimpleTypeKind::Character16; break;
186901095a5dSDimitry Andric     case 4: STK = SimpleTypeKind::Character32; break;
187001095a5dSDimitry Andric     }
187101095a5dSDimitry Andric     break;
187201095a5dSDimitry Andric   case dwarf::DW_ATE_signed_char:
187301095a5dSDimitry Andric     if (ByteSize == 1)
187401095a5dSDimitry Andric       STK = SimpleTypeKind::SignedCharacter;
187501095a5dSDimitry Andric     break;
187601095a5dSDimitry Andric   case dwarf::DW_ATE_unsigned_char:
187701095a5dSDimitry Andric     if (ByteSize == 1)
187801095a5dSDimitry Andric       STK = SimpleTypeKind::UnsignedCharacter;
187901095a5dSDimitry Andric     break;
188001095a5dSDimitry Andric   default:
188101095a5dSDimitry Andric     break;
188201095a5dSDimitry Andric   }
188301095a5dSDimitry Andric 
188401095a5dSDimitry Andric   // Apply some fixups based on the source-level type name.
1885c0981da4SDimitry Andric   // Include some amount of canonicalization from an old naming scheme Clang
1886c0981da4SDimitry Andric   // used to use for integer types (in an outdated effort to be compatible with
1887c0981da4SDimitry Andric   // GCC's debug info/GDB's behavior, which has since been addressed).
1888c0981da4SDimitry Andric   if (STK == SimpleTypeKind::Int32 &&
1889c0981da4SDimitry Andric       (Ty->getName() == "long int" || Ty->getName() == "long"))
189001095a5dSDimitry Andric     STK = SimpleTypeKind::Int32Long;
1891c0981da4SDimitry Andric   if (STK == SimpleTypeKind::UInt32 && (Ty->getName() == "long unsigned int" ||
1892c0981da4SDimitry Andric                                         Ty->getName() == "unsigned long"))
189301095a5dSDimitry Andric     STK = SimpleTypeKind::UInt32Long;
189401095a5dSDimitry Andric   if (STK == SimpleTypeKind::UInt16Short &&
189501095a5dSDimitry Andric       (Ty->getName() == "wchar_t" || Ty->getName() == "__wchar_t"))
189601095a5dSDimitry Andric     STK = SimpleTypeKind::WideCharacter;
189701095a5dSDimitry Andric   if ((STK == SimpleTypeKind::SignedCharacter ||
189801095a5dSDimitry Andric        STK == SimpleTypeKind::UnsignedCharacter) &&
189901095a5dSDimitry Andric       Ty->getName() == "char")
190001095a5dSDimitry Andric     STK = SimpleTypeKind::NarrowCharacter;
190101095a5dSDimitry Andric 
190201095a5dSDimitry Andric   return TypeIndex(STK);
190301095a5dSDimitry Andric }
190401095a5dSDimitry Andric 
lowerTypePointer(const DIDerivedType * Ty,PointerOptions PO)1905eb11fae6SDimitry Andric TypeIndex CodeViewDebug::lowerTypePointer(const DIDerivedType *Ty,
1906eb11fae6SDimitry Andric                                           PointerOptions PO) {
190701095a5dSDimitry Andric   TypeIndex PointeeTI = getTypeIndex(Ty->getBaseType());
190801095a5dSDimitry Andric 
1909eb11fae6SDimitry Andric   // Pointers to simple types without any options can use SimpleTypeMode, rather
1910eb11fae6SDimitry Andric   // than having a dedicated pointer type record.
1911eb11fae6SDimitry Andric   if (PointeeTI.isSimple() && PO == PointerOptions::None &&
191201095a5dSDimitry Andric       PointeeTI.getSimpleMode() == SimpleTypeMode::Direct &&
191301095a5dSDimitry Andric       Ty->getTag() == dwarf::DW_TAG_pointer_type) {
191401095a5dSDimitry Andric     SimpleTypeMode Mode = Ty->getSizeInBits() == 64
191501095a5dSDimitry Andric                               ? SimpleTypeMode::NearPointer64
191601095a5dSDimitry Andric                               : SimpleTypeMode::NearPointer32;
191701095a5dSDimitry Andric     return TypeIndex(PointeeTI.getSimpleKind(), Mode);
191801095a5dSDimitry Andric   }
191901095a5dSDimitry Andric 
192001095a5dSDimitry Andric   PointerKind PK =
192101095a5dSDimitry Andric       Ty->getSizeInBits() == 64 ? PointerKind::Near64 : PointerKind::Near32;
192201095a5dSDimitry Andric   PointerMode PM = PointerMode::Pointer;
192301095a5dSDimitry Andric   switch (Ty->getTag()) {
192401095a5dSDimitry Andric   default: llvm_unreachable("not a pointer tag type");
192501095a5dSDimitry Andric   case dwarf::DW_TAG_pointer_type:
192601095a5dSDimitry Andric     PM = PointerMode::Pointer;
192701095a5dSDimitry Andric     break;
192801095a5dSDimitry Andric   case dwarf::DW_TAG_reference_type:
192901095a5dSDimitry Andric     PM = PointerMode::LValueReference;
193001095a5dSDimitry Andric     break;
193101095a5dSDimitry Andric   case dwarf::DW_TAG_rvalue_reference_type:
193201095a5dSDimitry Andric     PM = PointerMode::RValueReference;
193301095a5dSDimitry Andric     break;
193401095a5dSDimitry Andric   }
1935eb11fae6SDimitry Andric 
1936d8e91e46SDimitry Andric   if (Ty->isObjectPointer())
1937d8e91e46SDimitry Andric     PO |= PointerOptions::Const;
1938d8e91e46SDimitry Andric 
193901095a5dSDimitry Andric   PointerRecord PR(PointeeTI, PK, PM, PO, Ty->getSizeInBits() / 8);
1940044eb2f6SDimitry Andric   return TypeTable.writeLeafType(PR);
194101095a5dSDimitry Andric }
194201095a5dSDimitry Andric 
194301095a5dSDimitry Andric static PointerToMemberRepresentation
translatePtrToMemberRep(unsigned SizeInBytes,bool IsPMF,unsigned Flags)194401095a5dSDimitry Andric translatePtrToMemberRep(unsigned SizeInBytes, bool IsPMF, unsigned Flags) {
194501095a5dSDimitry Andric   // SizeInBytes being zero generally implies that the member pointer type was
194601095a5dSDimitry Andric   // incomplete, which can happen if it is part of a function prototype. In this
194701095a5dSDimitry Andric   // case, use the unknown model instead of the general model.
194801095a5dSDimitry Andric   if (IsPMF) {
194901095a5dSDimitry Andric     switch (Flags & DINode::FlagPtrToMemberRep) {
195001095a5dSDimitry Andric     case 0:
195101095a5dSDimitry Andric       return SizeInBytes == 0 ? PointerToMemberRepresentation::Unknown
195201095a5dSDimitry Andric                               : PointerToMemberRepresentation::GeneralFunction;
195301095a5dSDimitry Andric     case DINode::FlagSingleInheritance:
195401095a5dSDimitry Andric       return PointerToMemberRepresentation::SingleInheritanceFunction;
195501095a5dSDimitry Andric     case DINode::FlagMultipleInheritance:
195601095a5dSDimitry Andric       return PointerToMemberRepresentation::MultipleInheritanceFunction;
195701095a5dSDimitry Andric     case DINode::FlagVirtualInheritance:
195801095a5dSDimitry Andric       return PointerToMemberRepresentation::VirtualInheritanceFunction;
195901095a5dSDimitry Andric     }
196001095a5dSDimitry Andric   } else {
196101095a5dSDimitry Andric     switch (Flags & DINode::FlagPtrToMemberRep) {
196201095a5dSDimitry Andric     case 0:
196301095a5dSDimitry Andric       return SizeInBytes == 0 ? PointerToMemberRepresentation::Unknown
196401095a5dSDimitry Andric                               : PointerToMemberRepresentation::GeneralData;
196501095a5dSDimitry Andric     case DINode::FlagSingleInheritance:
196601095a5dSDimitry Andric       return PointerToMemberRepresentation::SingleInheritanceData;
196701095a5dSDimitry Andric     case DINode::FlagMultipleInheritance:
196801095a5dSDimitry Andric       return PointerToMemberRepresentation::MultipleInheritanceData;
196901095a5dSDimitry Andric     case DINode::FlagVirtualInheritance:
197001095a5dSDimitry Andric       return PointerToMemberRepresentation::VirtualInheritanceData;
197101095a5dSDimitry Andric     }
197201095a5dSDimitry Andric   }
197301095a5dSDimitry Andric   llvm_unreachable("invalid ptr to member representation");
197401095a5dSDimitry Andric }
197501095a5dSDimitry Andric 
lowerTypeMemberPointer(const DIDerivedType * Ty,PointerOptions PO)1976eb11fae6SDimitry Andric TypeIndex CodeViewDebug::lowerTypeMemberPointer(const DIDerivedType *Ty,
1977eb11fae6SDimitry Andric                                                 PointerOptions PO) {
197801095a5dSDimitry Andric   assert(Ty->getTag() == dwarf::DW_TAG_ptr_to_member_type);
1979cfca06d7SDimitry Andric   bool IsPMF = isa<DISubroutineType>(Ty->getBaseType());
198001095a5dSDimitry Andric   TypeIndex ClassTI = getTypeIndex(Ty->getClassType());
1981cfca06d7SDimitry Andric   TypeIndex PointeeTI =
1982cfca06d7SDimitry Andric       getTypeIndex(Ty->getBaseType(), IsPMF ? Ty->getClassType() : nullptr);
1983eb11fae6SDimitry Andric   PointerKind PK = getPointerSizeInBytes() == 8 ? PointerKind::Near64
198401095a5dSDimitry Andric                                                 : PointerKind::Near32;
198501095a5dSDimitry Andric   PointerMode PM = IsPMF ? PointerMode::PointerToMemberFunction
198601095a5dSDimitry Andric                          : PointerMode::PointerToDataMember;
1987eb11fae6SDimitry Andric 
198801095a5dSDimitry Andric   assert(Ty->getSizeInBits() / 8 <= 0xff && "pointer size too big");
198901095a5dSDimitry Andric   uint8_t SizeInBytes = Ty->getSizeInBits() / 8;
199001095a5dSDimitry Andric   MemberPointerInfo MPI(
199101095a5dSDimitry Andric       ClassTI, translatePtrToMemberRep(SizeInBytes, IsPMF, Ty->getFlags()));
199201095a5dSDimitry Andric   PointerRecord PR(PointeeTI, PK, PM, PO, SizeInBytes, MPI);
1993044eb2f6SDimitry Andric   return TypeTable.writeLeafType(PR);
199401095a5dSDimitry Andric }
199501095a5dSDimitry Andric 
199601095a5dSDimitry Andric /// Given a DWARF calling convention, get the CodeView equivalent. If we don't
199701095a5dSDimitry Andric /// have a translation, use the NearC convention.
dwarfCCToCodeView(unsigned DwarfCC)199801095a5dSDimitry Andric static CallingConvention dwarfCCToCodeView(unsigned DwarfCC) {
199901095a5dSDimitry Andric   switch (DwarfCC) {
200001095a5dSDimitry Andric   case dwarf::DW_CC_normal:             return CallingConvention::NearC;
200101095a5dSDimitry Andric   case dwarf::DW_CC_BORLAND_msfastcall: return CallingConvention::NearFast;
200201095a5dSDimitry Andric   case dwarf::DW_CC_BORLAND_thiscall:   return CallingConvention::ThisCall;
200301095a5dSDimitry Andric   case dwarf::DW_CC_BORLAND_stdcall:    return CallingConvention::NearStdCall;
200401095a5dSDimitry Andric   case dwarf::DW_CC_BORLAND_pascal:     return CallingConvention::NearPascal;
200501095a5dSDimitry Andric   case dwarf::DW_CC_LLVM_vectorcall:    return CallingConvention::NearVector;
200601095a5dSDimitry Andric   }
200701095a5dSDimitry Andric   return CallingConvention::NearC;
200801095a5dSDimitry Andric }
200901095a5dSDimitry Andric 
lowerTypeModifier(const DIDerivedType * Ty)201001095a5dSDimitry Andric TypeIndex CodeViewDebug::lowerTypeModifier(const DIDerivedType *Ty) {
201101095a5dSDimitry Andric   ModifierOptions Mods = ModifierOptions::None;
2012eb11fae6SDimitry Andric   PointerOptions PO = PointerOptions::None;
201301095a5dSDimitry Andric   bool IsModifier = true;
201401095a5dSDimitry Andric   const DIType *BaseTy = Ty;
201501095a5dSDimitry Andric   while (IsModifier && BaseTy) {
2016b915e9e0SDimitry Andric     // FIXME: Need to add DWARF tags for __unaligned and _Atomic
201701095a5dSDimitry Andric     switch (BaseTy->getTag()) {
201801095a5dSDimitry Andric     case dwarf::DW_TAG_const_type:
201901095a5dSDimitry Andric       Mods |= ModifierOptions::Const;
2020eb11fae6SDimitry Andric       PO |= PointerOptions::Const;
202101095a5dSDimitry Andric       break;
202201095a5dSDimitry Andric     case dwarf::DW_TAG_volatile_type:
202301095a5dSDimitry Andric       Mods |= ModifierOptions::Volatile;
2024eb11fae6SDimitry Andric       PO |= PointerOptions::Volatile;
2025eb11fae6SDimitry Andric       break;
2026eb11fae6SDimitry Andric     case dwarf::DW_TAG_restrict_type:
2027eb11fae6SDimitry Andric       // Only pointer types be marked with __restrict. There is no known flag
2028eb11fae6SDimitry Andric       // for __restrict in LF_MODIFIER records.
2029eb11fae6SDimitry Andric       PO |= PointerOptions::Restrict;
203001095a5dSDimitry Andric       break;
203101095a5dSDimitry Andric     default:
203201095a5dSDimitry Andric       IsModifier = false;
203301095a5dSDimitry Andric       break;
203401095a5dSDimitry Andric     }
203501095a5dSDimitry Andric     if (IsModifier)
2036e6d15924SDimitry Andric       BaseTy = cast<DIDerivedType>(BaseTy)->getBaseType();
203701095a5dSDimitry Andric   }
2038eb11fae6SDimitry Andric 
2039eb11fae6SDimitry Andric   // Check if the inner type will use an LF_POINTER record. If so, the
2040eb11fae6SDimitry Andric   // qualifiers will go in the LF_POINTER record. This comes up for types like
2041eb11fae6SDimitry Andric   // 'int *const' and 'int *__restrict', not the more common cases like 'const
2042eb11fae6SDimitry Andric   // char *'.
2043eb11fae6SDimitry Andric   if (BaseTy) {
2044eb11fae6SDimitry Andric     switch (BaseTy->getTag()) {
2045eb11fae6SDimitry Andric     case dwarf::DW_TAG_pointer_type:
2046eb11fae6SDimitry Andric     case dwarf::DW_TAG_reference_type:
2047eb11fae6SDimitry Andric     case dwarf::DW_TAG_rvalue_reference_type:
2048eb11fae6SDimitry Andric       return lowerTypePointer(cast<DIDerivedType>(BaseTy), PO);
2049eb11fae6SDimitry Andric     case dwarf::DW_TAG_ptr_to_member_type:
2050eb11fae6SDimitry Andric       return lowerTypeMemberPointer(cast<DIDerivedType>(BaseTy), PO);
2051eb11fae6SDimitry Andric     default:
2052eb11fae6SDimitry Andric       break;
2053eb11fae6SDimitry Andric     }
2054eb11fae6SDimitry Andric   }
2055eb11fae6SDimitry Andric 
205601095a5dSDimitry Andric   TypeIndex ModifiedTI = getTypeIndex(BaseTy);
2057eb11fae6SDimitry Andric 
2058eb11fae6SDimitry Andric   // Return the base type index if there aren't any modifiers. For example, the
2059eb11fae6SDimitry Andric   // metadata could contain restrict wrappers around non-pointer types.
2060eb11fae6SDimitry Andric   if (Mods == ModifierOptions::None)
2061eb11fae6SDimitry Andric     return ModifiedTI;
2062eb11fae6SDimitry Andric 
206301095a5dSDimitry Andric   ModifierRecord MR(ModifiedTI, Mods);
2064044eb2f6SDimitry Andric   return TypeTable.writeLeafType(MR);
206501095a5dSDimitry Andric }
206601095a5dSDimitry Andric 
lowerTypeFunction(const DISubroutineType * Ty)206701095a5dSDimitry Andric TypeIndex CodeViewDebug::lowerTypeFunction(const DISubroutineType *Ty) {
206801095a5dSDimitry Andric   SmallVector<TypeIndex, 8> ReturnAndArgTypeIndices;
2069e6d15924SDimitry Andric   for (const DIType *ArgType : Ty->getTypeArray())
2070e6d15924SDimitry Andric     ReturnAndArgTypeIndices.push_back(getTypeIndex(ArgType));
207101095a5dSDimitry Andric 
2072eb11fae6SDimitry Andric   // MSVC uses type none for variadic argument.
2073eb11fae6SDimitry Andric   if (ReturnAndArgTypeIndices.size() > 1 &&
2074eb11fae6SDimitry Andric       ReturnAndArgTypeIndices.back() == TypeIndex::Void()) {
2075eb11fae6SDimitry Andric     ReturnAndArgTypeIndices.back() = TypeIndex::None();
2076eb11fae6SDimitry Andric   }
207701095a5dSDimitry Andric   TypeIndex ReturnTypeIndex = TypeIndex::Void();
2078e3b55780SDimitry Andric   ArrayRef<TypeIndex> ArgTypeIndices = std::nullopt;
207901095a5dSDimitry Andric   if (!ReturnAndArgTypeIndices.empty()) {
2080e3b55780SDimitry Andric     auto ReturnAndArgTypesRef = ArrayRef(ReturnAndArgTypeIndices);
208101095a5dSDimitry Andric     ReturnTypeIndex = ReturnAndArgTypesRef.front();
208201095a5dSDimitry Andric     ArgTypeIndices = ReturnAndArgTypesRef.drop_front();
208301095a5dSDimitry Andric   }
208401095a5dSDimitry Andric 
208501095a5dSDimitry Andric   ArgListRecord ArgListRec(TypeRecordKind::ArgList, ArgTypeIndices);
2086044eb2f6SDimitry Andric   TypeIndex ArgListIndex = TypeTable.writeLeafType(ArgListRec);
208701095a5dSDimitry Andric 
208801095a5dSDimitry Andric   CallingConvention CC = dwarfCCToCodeView(Ty->getCC());
208901095a5dSDimitry Andric 
2090d8e91e46SDimitry Andric   FunctionOptions FO = getFunctionOptions(Ty);
2091d8e91e46SDimitry Andric   ProcedureRecord Procedure(ReturnTypeIndex, CC, FO, ArgTypeIndices.size(),
2092d8e91e46SDimitry Andric                             ArgListIndex);
2093044eb2f6SDimitry Andric   return TypeTable.writeLeafType(Procedure);
209401095a5dSDimitry Andric }
209501095a5dSDimitry Andric 
lowerTypeMemberFunction(const DISubroutineType * Ty,const DIType * ClassTy,int ThisAdjustment,bool IsStaticMethod,FunctionOptions FO)209601095a5dSDimitry Andric TypeIndex CodeViewDebug::lowerTypeMemberFunction(const DISubroutineType *Ty,
209701095a5dSDimitry Andric                                                  const DIType *ClassTy,
2098044eb2f6SDimitry Andric                                                  int ThisAdjustment,
2099d8e91e46SDimitry Andric                                                  bool IsStaticMethod,
2100d8e91e46SDimitry Andric                                                  FunctionOptions FO) {
210101095a5dSDimitry Andric   // Lower the containing class type.
210201095a5dSDimitry Andric   TypeIndex ClassType = getTypeIndex(ClassTy);
210301095a5dSDimitry Andric 
2104d8e91e46SDimitry Andric   DITypeRefArray ReturnAndArgs = Ty->getTypeArray();
2105d8e91e46SDimitry Andric 
2106d8e91e46SDimitry Andric   unsigned Index = 0;
2107d8e91e46SDimitry Andric   SmallVector<TypeIndex, 8> ArgTypeIndices;
2108e6d15924SDimitry Andric   TypeIndex ReturnTypeIndex = TypeIndex::Void();
2109e6d15924SDimitry Andric   if (ReturnAndArgs.size() > Index) {
2110e6d15924SDimitry Andric     ReturnTypeIndex = getTypeIndex(ReturnAndArgs[Index++]);
2111e6d15924SDimitry Andric   }
2112d8e91e46SDimitry Andric 
2113d8e91e46SDimitry Andric   // If the first argument is a pointer type and this isn't a static method,
2114d8e91e46SDimitry Andric   // treat it as the special 'this' parameter, which is encoded separately from
2115d8e91e46SDimitry Andric   // the arguments.
2116d8e91e46SDimitry Andric   TypeIndex ThisTypeIndex;
2117d8e91e46SDimitry Andric   if (!IsStaticMethod && ReturnAndArgs.size() > Index) {
2118d8e91e46SDimitry Andric     if (const DIDerivedType *PtrTy =
2119e6d15924SDimitry Andric             dyn_cast_or_null<DIDerivedType>(ReturnAndArgs[Index])) {
2120d8e91e46SDimitry Andric       if (PtrTy->getTag() == dwarf::DW_TAG_pointer_type) {
2121d8e91e46SDimitry Andric         ThisTypeIndex = getTypeIndexForThisPtr(PtrTy, Ty);
2122d8e91e46SDimitry Andric         Index++;
2123d8e91e46SDimitry Andric       }
2124d8e91e46SDimitry Andric     }
2125d8e91e46SDimitry Andric   }
2126d8e91e46SDimitry Andric 
2127d8e91e46SDimitry Andric   while (Index < ReturnAndArgs.size())
2128d8e91e46SDimitry Andric     ArgTypeIndices.push_back(getTypeIndex(ReturnAndArgs[Index++]));
212901095a5dSDimitry Andric 
2130eb11fae6SDimitry Andric   // MSVC uses type none for variadic argument.
2131d8e91e46SDimitry Andric   if (!ArgTypeIndices.empty() && ArgTypeIndices.back() == TypeIndex::Void())
2132d8e91e46SDimitry Andric     ArgTypeIndices.back() = TypeIndex::None();
213301095a5dSDimitry Andric 
213401095a5dSDimitry Andric   ArgListRecord ArgListRec(TypeRecordKind::ArgList, ArgTypeIndices);
2135044eb2f6SDimitry Andric   TypeIndex ArgListIndex = TypeTable.writeLeafType(ArgListRec);
213601095a5dSDimitry Andric 
213701095a5dSDimitry Andric   CallingConvention CC = dwarfCCToCodeView(Ty->getCC());
213801095a5dSDimitry Andric 
2139d8e91e46SDimitry Andric   MemberFunctionRecord MFR(ReturnTypeIndex, ClassType, ThisTypeIndex, CC, FO,
2140d8e91e46SDimitry Andric                            ArgTypeIndices.size(), ArgListIndex, ThisAdjustment);
2141044eb2f6SDimitry Andric   return TypeTable.writeLeafType(MFR);
214201095a5dSDimitry Andric }
214301095a5dSDimitry Andric 
lowerTypeVFTableShape(const DIDerivedType * Ty)2144b915e9e0SDimitry Andric TypeIndex CodeViewDebug::lowerTypeVFTableShape(const DIDerivedType *Ty) {
2145d99dafe2SDimitry Andric   unsigned VSlotCount =
2146d99dafe2SDimitry Andric       Ty->getSizeInBits() / (8 * Asm->MAI->getCodePointerSize());
2147b915e9e0SDimitry Andric   SmallVector<VFTableSlotKind, 4> Slots(VSlotCount, VFTableSlotKind::Near);
2148b915e9e0SDimitry Andric 
2149b915e9e0SDimitry Andric   VFTableShapeRecord VFTSR(Slots);
2150044eb2f6SDimitry Andric   return TypeTable.writeLeafType(VFTSR);
2151b915e9e0SDimitry Andric }
2152b915e9e0SDimitry Andric 
translateAccessFlags(unsigned RecordTag,unsigned Flags)215301095a5dSDimitry Andric static MemberAccess translateAccessFlags(unsigned RecordTag, unsigned Flags) {
215401095a5dSDimitry Andric   switch (Flags & DINode::FlagAccessibility) {
215501095a5dSDimitry Andric   case DINode::FlagPrivate:   return MemberAccess::Private;
215601095a5dSDimitry Andric   case DINode::FlagPublic:    return MemberAccess::Public;
215701095a5dSDimitry Andric   case DINode::FlagProtected: return MemberAccess::Protected;
215801095a5dSDimitry Andric   case 0:
215901095a5dSDimitry Andric     // If there was no explicit access control, provide the default for the tag.
216001095a5dSDimitry Andric     return RecordTag == dwarf::DW_TAG_class_type ? MemberAccess::Private
216101095a5dSDimitry Andric                                                  : MemberAccess::Public;
216201095a5dSDimitry Andric   }
216301095a5dSDimitry Andric   llvm_unreachable("access flags are exclusive");
216401095a5dSDimitry Andric }
216501095a5dSDimitry Andric 
translateMethodOptionFlags(const DISubprogram * SP)216601095a5dSDimitry Andric static MethodOptions translateMethodOptionFlags(const DISubprogram *SP) {
216701095a5dSDimitry Andric   if (SP->isArtificial())
216801095a5dSDimitry Andric     return MethodOptions::CompilerGenerated;
216901095a5dSDimitry Andric 
217001095a5dSDimitry Andric   // FIXME: Handle other MethodOptions.
217101095a5dSDimitry Andric 
217201095a5dSDimitry Andric   return MethodOptions::None;
217301095a5dSDimitry Andric }
217401095a5dSDimitry Andric 
translateMethodKindFlags(const DISubprogram * SP,bool Introduced)217501095a5dSDimitry Andric static MethodKind translateMethodKindFlags(const DISubprogram *SP,
217601095a5dSDimitry Andric                                            bool Introduced) {
2177044eb2f6SDimitry Andric   if (SP->getFlags() & DINode::FlagStaticMember)
2178044eb2f6SDimitry Andric     return MethodKind::Static;
2179044eb2f6SDimitry Andric 
218001095a5dSDimitry Andric   switch (SP->getVirtuality()) {
218101095a5dSDimitry Andric   case dwarf::DW_VIRTUALITY_none:
218201095a5dSDimitry Andric     break;
218301095a5dSDimitry Andric   case dwarf::DW_VIRTUALITY_virtual:
218401095a5dSDimitry Andric     return Introduced ? MethodKind::IntroducingVirtual : MethodKind::Virtual;
218501095a5dSDimitry Andric   case dwarf::DW_VIRTUALITY_pure_virtual:
218601095a5dSDimitry Andric     return Introduced ? MethodKind::PureIntroducingVirtual
218701095a5dSDimitry Andric                       : MethodKind::PureVirtual;
218801095a5dSDimitry Andric   default:
218901095a5dSDimitry Andric     llvm_unreachable("unhandled virtuality case");
219001095a5dSDimitry Andric   }
219101095a5dSDimitry Andric 
219201095a5dSDimitry Andric   return MethodKind::Vanilla;
219301095a5dSDimitry Andric }
219401095a5dSDimitry Andric 
getRecordKind(const DICompositeType * Ty)219501095a5dSDimitry Andric static TypeRecordKind getRecordKind(const DICompositeType *Ty) {
219601095a5dSDimitry Andric   switch (Ty->getTag()) {
2197344a3780SDimitry Andric   case dwarf::DW_TAG_class_type:
2198344a3780SDimitry Andric     return TypeRecordKind::Class;
2199344a3780SDimitry Andric   case dwarf::DW_TAG_structure_type:
2200344a3780SDimitry Andric     return TypeRecordKind::Struct;
2201344a3780SDimitry Andric   default:
220201095a5dSDimitry Andric     llvm_unreachable("unexpected tag");
220301095a5dSDimitry Andric   }
2204344a3780SDimitry Andric }
220501095a5dSDimitry Andric 
220601095a5dSDimitry Andric /// Return ClassOptions that should be present on both the forward declaration
220701095a5dSDimitry Andric /// and the defintion of a tag type.
getCommonClassOptions(const DICompositeType * Ty)220801095a5dSDimitry Andric static ClassOptions getCommonClassOptions(const DICompositeType *Ty) {
220901095a5dSDimitry Andric   ClassOptions CO = ClassOptions::None;
221001095a5dSDimitry Andric 
221101095a5dSDimitry Andric   // MSVC always sets this flag, even for local types. Clang doesn't always
221201095a5dSDimitry Andric   // appear to give every type a linkage name, which may be problematic for us.
221301095a5dSDimitry Andric   // FIXME: Investigate the consequences of not following them here.
221401095a5dSDimitry Andric   if (!Ty->getIdentifier().empty())
221501095a5dSDimitry Andric     CO |= ClassOptions::HasUniqueName;
221601095a5dSDimitry Andric 
221701095a5dSDimitry Andric   // Put the Nested flag on a type if it appears immediately inside a tag type.
221801095a5dSDimitry Andric   // Do not walk the scope chain. Do not attempt to compute ContainsNestedClass
221901095a5dSDimitry Andric   // here. That flag is only set on definitions, and not forward declarations.
2220e6d15924SDimitry Andric   const DIScope *ImmediateScope = Ty->getScope();
222101095a5dSDimitry Andric   if (ImmediateScope && isa<DICompositeType>(ImmediateScope))
222201095a5dSDimitry Andric     CO |= ClassOptions::Nested;
222301095a5dSDimitry Andric 
2224d8e91e46SDimitry Andric   // Put the Scoped flag on function-local types. MSVC puts this flag for enum
2225d8e91e46SDimitry Andric   // type only when it has an immediate function scope. Clang never puts enums
2226d8e91e46SDimitry Andric   // inside DILexicalBlock scopes. Enum types, as generated by clang, are
2227d8e91e46SDimitry Andric   // always in function, class, or file scopes.
2228d8e91e46SDimitry Andric   if (Ty->getTag() == dwarf::DW_TAG_enumeration_type) {
2229d8e91e46SDimitry Andric     if (ImmediateScope && isa<DISubprogram>(ImmediateScope))
2230d8e91e46SDimitry Andric       CO |= ClassOptions::Scoped;
2231d8e91e46SDimitry Andric   } else {
223201095a5dSDimitry Andric     for (const DIScope *Scope = ImmediateScope; Scope != nullptr;
2233e6d15924SDimitry Andric          Scope = Scope->getScope()) {
223401095a5dSDimitry Andric       if (isa<DISubprogram>(Scope)) {
223501095a5dSDimitry Andric         CO |= ClassOptions::Scoped;
223601095a5dSDimitry Andric         break;
223701095a5dSDimitry Andric       }
223801095a5dSDimitry Andric     }
2239d8e91e46SDimitry Andric   }
224001095a5dSDimitry Andric 
224101095a5dSDimitry Andric   return CO;
224201095a5dSDimitry Andric }
224301095a5dSDimitry Andric 
addUDTSrcLine(const DIType * Ty,TypeIndex TI)2244eb11fae6SDimitry Andric void CodeViewDebug::addUDTSrcLine(const DIType *Ty, TypeIndex TI) {
2245eb11fae6SDimitry Andric   switch (Ty->getTag()) {
2246eb11fae6SDimitry Andric   case dwarf::DW_TAG_class_type:
2247eb11fae6SDimitry Andric   case dwarf::DW_TAG_structure_type:
2248eb11fae6SDimitry Andric   case dwarf::DW_TAG_union_type:
2249eb11fae6SDimitry Andric   case dwarf::DW_TAG_enumeration_type:
2250eb11fae6SDimitry Andric     break;
2251eb11fae6SDimitry Andric   default:
2252eb11fae6SDimitry Andric     return;
2253eb11fae6SDimitry Andric   }
2254eb11fae6SDimitry Andric 
2255eb11fae6SDimitry Andric   if (const auto *File = Ty->getFile()) {
2256eb11fae6SDimitry Andric     StringIdRecord SIDR(TypeIndex(0x0), getFullFilepath(File));
2257eb11fae6SDimitry Andric     TypeIndex SIDI = TypeTable.writeLeafType(SIDR);
2258eb11fae6SDimitry Andric 
2259eb11fae6SDimitry Andric     UdtSourceLineRecord USLR(TI, SIDI, Ty->getLine());
2260eb11fae6SDimitry Andric     TypeTable.writeLeafType(USLR);
2261eb11fae6SDimitry Andric   }
2262eb11fae6SDimitry Andric }
2263eb11fae6SDimitry Andric 
lowerTypeEnum(const DICompositeType * Ty)226401095a5dSDimitry Andric TypeIndex CodeViewDebug::lowerTypeEnum(const DICompositeType *Ty) {
226501095a5dSDimitry Andric   ClassOptions CO = getCommonClassOptions(Ty);
226601095a5dSDimitry Andric   TypeIndex FTI;
226701095a5dSDimitry Andric   unsigned EnumeratorCount = 0;
226801095a5dSDimitry Andric 
226901095a5dSDimitry Andric   if (Ty->isForwardDecl()) {
227001095a5dSDimitry Andric     CO |= ClassOptions::ForwardReference;
227101095a5dSDimitry Andric   } else {
2272044eb2f6SDimitry Andric     ContinuationRecordBuilder ContinuationBuilder;
2273044eb2f6SDimitry Andric     ContinuationBuilder.begin(ContinuationRecordKind::FieldList);
227401095a5dSDimitry Andric     for (const DINode *Element : Ty->getElements()) {
227501095a5dSDimitry Andric       // We assume that the frontend provides all members in source declaration
227601095a5dSDimitry Andric       // order, which is what MSVC does.
227701095a5dSDimitry Andric       if (auto *Enumerator = dyn_cast_or_null<DIEnumerator>(Element)) {
2278344a3780SDimitry Andric         // FIXME: Is it correct to always emit these as unsigned here?
2279b915e9e0SDimitry Andric         EnumeratorRecord ER(MemberAccess::Public,
2280cfca06d7SDimitry Andric                             APSInt(Enumerator->getValue(), true),
2281b915e9e0SDimitry Andric                             Enumerator->getName());
2282044eb2f6SDimitry Andric         ContinuationBuilder.writeMemberType(ER);
228301095a5dSDimitry Andric         EnumeratorCount++;
228401095a5dSDimitry Andric       }
228501095a5dSDimitry Andric     }
2286044eb2f6SDimitry Andric     FTI = TypeTable.insertRecord(ContinuationBuilder);
228701095a5dSDimitry Andric   }
228801095a5dSDimitry Andric 
228901095a5dSDimitry Andric   std::string FullName = getFullyQualifiedName(Ty);
229001095a5dSDimitry Andric 
2291b915e9e0SDimitry Andric   EnumRecord ER(EnumeratorCount, CO, FTI, FullName, Ty->getIdentifier(),
2292b915e9e0SDimitry Andric                 getTypeIndex(Ty->getBaseType()));
2293eb11fae6SDimitry Andric   TypeIndex EnumTI = TypeTable.writeLeafType(ER);
2294eb11fae6SDimitry Andric 
2295eb11fae6SDimitry Andric   addUDTSrcLine(Ty, EnumTI);
2296eb11fae6SDimitry Andric 
2297eb11fae6SDimitry Andric   return EnumTI;
229801095a5dSDimitry Andric }
229901095a5dSDimitry Andric 
230001095a5dSDimitry Andric //===----------------------------------------------------------------------===//
230101095a5dSDimitry Andric // ClassInfo
230201095a5dSDimitry Andric //===----------------------------------------------------------------------===//
230301095a5dSDimitry Andric 
230401095a5dSDimitry Andric struct llvm::ClassInfo {
230501095a5dSDimitry Andric   struct MemberInfo {
230601095a5dSDimitry Andric     const DIDerivedType *MemberTypeNode;
230701095a5dSDimitry Andric     uint64_t BaseOffset;
230801095a5dSDimitry Andric   };
230901095a5dSDimitry Andric   // [MemberInfo]
23107ab83427SDimitry Andric   using MemberList = std::vector<MemberInfo>;
231101095a5dSDimitry Andric 
23127ab83427SDimitry Andric   using MethodsList = TinyPtrVector<const DISubprogram *>;
231301095a5dSDimitry Andric   // MethodName -> MethodsList
23147ab83427SDimitry Andric   using MethodsMap = MapVector<MDString *, MethodsList>;
231501095a5dSDimitry Andric 
231601095a5dSDimitry Andric   /// Base classes.
231701095a5dSDimitry Andric   std::vector<const DIDerivedType *> Inheritance;
231801095a5dSDimitry Andric 
231901095a5dSDimitry Andric   /// Direct members.
232001095a5dSDimitry Andric   MemberList Members;
232101095a5dSDimitry Andric   // Direct overloaded methods gathered by name.
232201095a5dSDimitry Andric   MethodsMap Methods;
232301095a5dSDimitry Andric 
2324b915e9e0SDimitry Andric   TypeIndex VShapeTI;
2325b915e9e0SDimitry Andric 
2326044eb2f6SDimitry Andric   std::vector<const DIType *> NestedTypes;
232701095a5dSDimitry Andric };
232801095a5dSDimitry Andric 
clear()232901095a5dSDimitry Andric void CodeViewDebug::clear() {
233001095a5dSDimitry Andric   assert(CurFn == nullptr);
233101095a5dSDimitry Andric   FileIdMap.clear();
233201095a5dSDimitry Andric   FnDebugInfo.clear();
233301095a5dSDimitry Andric   FileToFilepathMap.clear();
233401095a5dSDimitry Andric   LocalUDTs.clear();
233501095a5dSDimitry Andric   GlobalUDTs.clear();
233601095a5dSDimitry Andric   TypeIndices.clear();
233701095a5dSDimitry Andric   CompleteTypeIndices.clear();
2338d8e91e46SDimitry Andric   ScopeGlobals.clear();
2339c0981da4SDimitry Andric   CVGlobalVariableOffsets.clear();
234001095a5dSDimitry Andric }
234101095a5dSDimitry Andric 
collectMemberInfo(ClassInfo & Info,const DIDerivedType * DDTy)234201095a5dSDimitry Andric void CodeViewDebug::collectMemberInfo(ClassInfo &Info,
234301095a5dSDimitry Andric                                       const DIDerivedType *DDTy) {
234401095a5dSDimitry Andric   if (!DDTy->getName().empty()) {
234501095a5dSDimitry Andric     Info.Members.push_back({DDTy, 0});
2346b60736ecSDimitry Andric 
2347b60736ecSDimitry Andric     // Collect static const data members with values.
2348b60736ecSDimitry Andric     if ((DDTy->getFlags() & DINode::FlagStaticMember) ==
2349b60736ecSDimitry Andric         DINode::FlagStaticMember) {
2350b60736ecSDimitry Andric       if (DDTy->getConstant() && (isa<ConstantInt>(DDTy->getConstant()) ||
2351b60736ecSDimitry Andric                                   isa<ConstantFP>(DDTy->getConstant())))
2352b60736ecSDimitry Andric         StaticConstMembers.push_back(DDTy);
2353b60736ecSDimitry Andric     }
2354b60736ecSDimitry Andric 
235501095a5dSDimitry Andric     return;
235601095a5dSDimitry Andric   }
2357eb11fae6SDimitry Andric 
2358eb11fae6SDimitry Andric   // An unnamed member may represent a nested struct or union. Attempt to
2359eb11fae6SDimitry Andric   // interpret the unnamed member as a DICompositeType possibly wrapped in
2360eb11fae6SDimitry Andric   // qualifier types. Add all the indirect fields to the current record if that
2361eb11fae6SDimitry Andric   // succeeds, and drop the member if that fails.
236201095a5dSDimitry Andric   assert((DDTy->getOffsetInBits() % 8) == 0 && "Unnamed bitfield member!");
236301095a5dSDimitry Andric   uint64_t Offset = DDTy->getOffsetInBits();
2364e6d15924SDimitry Andric   const DIType *Ty = DDTy->getBaseType();
2365eb11fae6SDimitry Andric   bool FullyResolved = false;
2366eb11fae6SDimitry Andric   while (!FullyResolved) {
2367eb11fae6SDimitry Andric     switch (Ty->getTag()) {
2368eb11fae6SDimitry Andric     case dwarf::DW_TAG_const_type:
2369eb11fae6SDimitry Andric     case dwarf::DW_TAG_volatile_type:
2370eb11fae6SDimitry Andric       // FIXME: we should apply the qualifier types to the indirect fields
2371eb11fae6SDimitry Andric       // rather than dropping them.
2372e6d15924SDimitry Andric       Ty = cast<DIDerivedType>(Ty)->getBaseType();
2373eb11fae6SDimitry Andric       break;
2374eb11fae6SDimitry Andric     default:
2375eb11fae6SDimitry Andric       FullyResolved = true;
2376eb11fae6SDimitry Andric       break;
2377eb11fae6SDimitry Andric     }
2378eb11fae6SDimitry Andric   }
2379eb11fae6SDimitry Andric 
2380eb11fae6SDimitry Andric   const DICompositeType *DCTy = dyn_cast<DICompositeType>(Ty);
2381eb11fae6SDimitry Andric   if (!DCTy)
2382eb11fae6SDimitry Andric     return;
2383eb11fae6SDimitry Andric 
238401095a5dSDimitry Andric   ClassInfo NestedInfo = collectClassInfo(DCTy);
238501095a5dSDimitry Andric   for (const ClassInfo::MemberInfo &IndirectField : NestedInfo.Members)
238601095a5dSDimitry Andric     Info.Members.push_back(
238701095a5dSDimitry Andric         {IndirectField.MemberTypeNode, IndirectField.BaseOffset + Offset});
238801095a5dSDimitry Andric }
238901095a5dSDimitry Andric 
collectClassInfo(const DICompositeType * Ty)239001095a5dSDimitry Andric ClassInfo CodeViewDebug::collectClassInfo(const DICompositeType *Ty) {
239101095a5dSDimitry Andric   ClassInfo Info;
239201095a5dSDimitry Andric   // Add elements to structure type.
239301095a5dSDimitry Andric   DINodeArray Elements = Ty->getElements();
239401095a5dSDimitry Andric   for (auto *Element : Elements) {
239501095a5dSDimitry Andric     // We assume that the frontend provides all members in source declaration
239601095a5dSDimitry Andric     // order, which is what MSVC does.
239701095a5dSDimitry Andric     if (!Element)
239801095a5dSDimitry Andric       continue;
239901095a5dSDimitry Andric     if (auto *SP = dyn_cast<DISubprogram>(Element)) {
240001095a5dSDimitry Andric       Info.Methods[SP->getRawName()].push_back(SP);
240101095a5dSDimitry Andric     } else if (auto *DDTy = dyn_cast<DIDerivedType>(Element)) {
240201095a5dSDimitry Andric       if (DDTy->getTag() == dwarf::DW_TAG_member) {
240301095a5dSDimitry Andric         collectMemberInfo(Info, DDTy);
240401095a5dSDimitry Andric       } else if (DDTy->getTag() == dwarf::DW_TAG_inheritance) {
240501095a5dSDimitry Andric         Info.Inheritance.push_back(DDTy);
2406b915e9e0SDimitry Andric       } else if (DDTy->getTag() == dwarf::DW_TAG_pointer_type &&
2407b915e9e0SDimitry Andric                  DDTy->getName() == "__vtbl_ptr_type") {
2408b915e9e0SDimitry Andric         Info.VShapeTI = getTypeIndex(DDTy);
2409044eb2f6SDimitry Andric       } else if (DDTy->getTag() == dwarf::DW_TAG_typedef) {
2410044eb2f6SDimitry Andric         Info.NestedTypes.push_back(DDTy);
241101095a5dSDimitry Andric       } else if (DDTy->getTag() == dwarf::DW_TAG_friend) {
241201095a5dSDimitry Andric         // Ignore friend members. It appears that MSVC emitted info about
241301095a5dSDimitry Andric         // friends in the past, but modern versions do not.
241401095a5dSDimitry Andric       }
241501095a5dSDimitry Andric     } else if (auto *Composite = dyn_cast<DICompositeType>(Element)) {
2416044eb2f6SDimitry Andric       Info.NestedTypes.push_back(Composite);
241701095a5dSDimitry Andric     }
241801095a5dSDimitry Andric     // Skip other unrecognized kinds of elements.
241901095a5dSDimitry Andric   }
242001095a5dSDimitry Andric   return Info;
242101095a5dSDimitry Andric }
242201095a5dSDimitry Andric 
shouldAlwaysEmitCompleteClassType(const DICompositeType * Ty)2423eb11fae6SDimitry Andric static bool shouldAlwaysEmitCompleteClassType(const DICompositeType *Ty) {
2424eb11fae6SDimitry Andric   // This routine is used by lowerTypeClass and lowerTypeUnion to determine
2425eb11fae6SDimitry Andric   // if a complete type should be emitted instead of a forward reference.
2426eb11fae6SDimitry Andric   return Ty->getName().empty() && Ty->getIdentifier().empty() &&
2427eb11fae6SDimitry Andric       !Ty->isForwardDecl();
2428eb11fae6SDimitry Andric }
2429eb11fae6SDimitry Andric 
lowerTypeClass(const DICompositeType * Ty)243001095a5dSDimitry Andric TypeIndex CodeViewDebug::lowerTypeClass(const DICompositeType *Ty) {
2431eb11fae6SDimitry Andric   // Emit the complete type for unnamed structs.  C++ classes with methods
2432eb11fae6SDimitry Andric   // which have a circular reference back to the class type are expected to
2433eb11fae6SDimitry Andric   // be named by the front-end and should not be "unnamed".  C unnamed
2434eb11fae6SDimitry Andric   // structs should not have circular references.
2435eb11fae6SDimitry Andric   if (shouldAlwaysEmitCompleteClassType(Ty)) {
2436eb11fae6SDimitry Andric     // If this unnamed complete type is already in the process of being defined
2437eb11fae6SDimitry Andric     // then the description of the type is malformed and cannot be emitted
2438eb11fae6SDimitry Andric     // into CodeView correctly so report a fatal error.
2439eb11fae6SDimitry Andric     auto I = CompleteTypeIndices.find(Ty);
2440eb11fae6SDimitry Andric     if (I != CompleteTypeIndices.end() && I->second == TypeIndex())
2441eb11fae6SDimitry Andric       report_fatal_error("cannot debug circular reference to unnamed type");
2442eb11fae6SDimitry Andric     return getCompleteTypeIndex(Ty);
2443eb11fae6SDimitry Andric   }
2444eb11fae6SDimitry Andric 
244501095a5dSDimitry Andric   // First, construct the forward decl.  Don't look into Ty to compute the
244601095a5dSDimitry Andric   // forward decl options, since it might not be available in all TUs.
244701095a5dSDimitry Andric   TypeRecordKind Kind = getRecordKind(Ty);
244801095a5dSDimitry Andric   ClassOptions CO =
244901095a5dSDimitry Andric       ClassOptions::ForwardReference | getCommonClassOptions(Ty);
245001095a5dSDimitry Andric   std::string FullName = getFullyQualifiedName(Ty);
2451b915e9e0SDimitry Andric   ClassRecord CR(Kind, 0, CO, TypeIndex(), TypeIndex(), TypeIndex(), 0,
2452b915e9e0SDimitry Andric                  FullName, Ty->getIdentifier());
2453044eb2f6SDimitry Andric   TypeIndex FwdDeclTI = TypeTable.writeLeafType(CR);
245401095a5dSDimitry Andric   if (!Ty->isForwardDecl())
245501095a5dSDimitry Andric     DeferredCompleteTypes.push_back(Ty);
245601095a5dSDimitry Andric   return FwdDeclTI;
245701095a5dSDimitry Andric }
245801095a5dSDimitry Andric 
lowerCompleteTypeClass(const DICompositeType * Ty)245901095a5dSDimitry Andric TypeIndex CodeViewDebug::lowerCompleteTypeClass(const DICompositeType *Ty) {
246001095a5dSDimitry Andric   // Construct the field list and complete type record.
246101095a5dSDimitry Andric   TypeRecordKind Kind = getRecordKind(Ty);
246201095a5dSDimitry Andric   ClassOptions CO = getCommonClassOptions(Ty);
246301095a5dSDimitry Andric   TypeIndex FieldTI;
246401095a5dSDimitry Andric   TypeIndex VShapeTI;
246501095a5dSDimitry Andric   unsigned FieldCount;
246601095a5dSDimitry Andric   bool ContainsNestedClass;
246701095a5dSDimitry Andric   std::tie(FieldTI, VShapeTI, FieldCount, ContainsNestedClass) =
246801095a5dSDimitry Andric       lowerRecordFieldList(Ty);
246901095a5dSDimitry Andric 
247001095a5dSDimitry Andric   if (ContainsNestedClass)
247101095a5dSDimitry Andric     CO |= ClassOptions::ContainsNestedClass;
247201095a5dSDimitry Andric 
2473e6d15924SDimitry Andric   // MSVC appears to set this flag by searching any destructor or method with
2474e6d15924SDimitry Andric   // FunctionOptions::Constructor among the emitted members. Clang AST has all
2475e6d15924SDimitry Andric   // the members, however special member functions are not yet emitted into
2476e6d15924SDimitry Andric   // debug information. For now checking a class's non-triviality seems enough.
2477e6d15924SDimitry Andric   // FIXME: not true for a nested unnamed struct.
2478e6d15924SDimitry Andric   if (isNonTrivial(Ty))
2479e6d15924SDimitry Andric     CO |= ClassOptions::HasConstructorOrDestructor;
2480e6d15924SDimitry Andric 
248101095a5dSDimitry Andric   std::string FullName = getFullyQualifiedName(Ty);
248201095a5dSDimitry Andric 
248301095a5dSDimitry Andric   uint64_t SizeInBytes = Ty->getSizeInBits() / 8;
248401095a5dSDimitry Andric 
2485b915e9e0SDimitry Andric   ClassRecord CR(Kind, FieldCount, CO, FieldTI, TypeIndex(), VShapeTI,
2486b915e9e0SDimitry Andric                  SizeInBytes, FullName, Ty->getIdentifier());
2487044eb2f6SDimitry Andric   TypeIndex ClassTI = TypeTable.writeLeafType(CR);
248801095a5dSDimitry Andric 
2489eb11fae6SDimitry Andric   addUDTSrcLine(Ty, ClassTI);
249001095a5dSDimitry Andric 
2491044eb2f6SDimitry Andric   addToUDTs(Ty);
249201095a5dSDimitry Andric 
249301095a5dSDimitry Andric   return ClassTI;
249401095a5dSDimitry Andric }
249501095a5dSDimitry Andric 
lowerTypeUnion(const DICompositeType * Ty)249601095a5dSDimitry Andric TypeIndex CodeViewDebug::lowerTypeUnion(const DICompositeType *Ty) {
2497eb11fae6SDimitry Andric   // Emit the complete type for unnamed unions.
2498eb11fae6SDimitry Andric   if (shouldAlwaysEmitCompleteClassType(Ty))
2499eb11fae6SDimitry Andric     return getCompleteTypeIndex(Ty);
2500eb11fae6SDimitry Andric 
250101095a5dSDimitry Andric   ClassOptions CO =
250201095a5dSDimitry Andric       ClassOptions::ForwardReference | getCommonClassOptions(Ty);
250301095a5dSDimitry Andric   std::string FullName = getFullyQualifiedName(Ty);
2504b915e9e0SDimitry Andric   UnionRecord UR(0, CO, TypeIndex(), 0, FullName, Ty->getIdentifier());
2505044eb2f6SDimitry Andric   TypeIndex FwdDeclTI = TypeTable.writeLeafType(UR);
250601095a5dSDimitry Andric   if (!Ty->isForwardDecl())
250701095a5dSDimitry Andric     DeferredCompleteTypes.push_back(Ty);
250801095a5dSDimitry Andric   return FwdDeclTI;
250901095a5dSDimitry Andric }
251001095a5dSDimitry Andric 
lowerCompleteTypeUnion(const DICompositeType * Ty)251101095a5dSDimitry Andric TypeIndex CodeViewDebug::lowerCompleteTypeUnion(const DICompositeType *Ty) {
251201095a5dSDimitry Andric   ClassOptions CO = ClassOptions::Sealed | getCommonClassOptions(Ty);
251301095a5dSDimitry Andric   TypeIndex FieldTI;
251401095a5dSDimitry Andric   unsigned FieldCount;
251501095a5dSDimitry Andric   bool ContainsNestedClass;
251601095a5dSDimitry Andric   std::tie(FieldTI, std::ignore, FieldCount, ContainsNestedClass) =
251701095a5dSDimitry Andric       lowerRecordFieldList(Ty);
251801095a5dSDimitry Andric 
251901095a5dSDimitry Andric   if (ContainsNestedClass)
252001095a5dSDimitry Andric     CO |= ClassOptions::ContainsNestedClass;
252101095a5dSDimitry Andric 
252201095a5dSDimitry Andric   uint64_t SizeInBytes = Ty->getSizeInBits() / 8;
252301095a5dSDimitry Andric   std::string FullName = getFullyQualifiedName(Ty);
252401095a5dSDimitry Andric 
2525b915e9e0SDimitry Andric   UnionRecord UR(FieldCount, CO, FieldTI, SizeInBytes, FullName,
2526b915e9e0SDimitry Andric                  Ty->getIdentifier());
2527044eb2f6SDimitry Andric   TypeIndex UnionTI = TypeTable.writeLeafType(UR);
252801095a5dSDimitry Andric 
2529eb11fae6SDimitry Andric   addUDTSrcLine(Ty, UnionTI);
2530044eb2f6SDimitry Andric 
2531044eb2f6SDimitry Andric   addToUDTs(Ty);
253201095a5dSDimitry Andric 
253301095a5dSDimitry Andric   return UnionTI;
253401095a5dSDimitry Andric }
253501095a5dSDimitry Andric 
253601095a5dSDimitry Andric std::tuple<TypeIndex, TypeIndex, unsigned, bool>
lowerRecordFieldList(const DICompositeType * Ty)253701095a5dSDimitry Andric CodeViewDebug::lowerRecordFieldList(const DICompositeType *Ty) {
253801095a5dSDimitry Andric   // Manually count members. MSVC appears to count everything that generates a
253901095a5dSDimitry Andric   // field list record. Each individual overload in a method overload group
254001095a5dSDimitry Andric   // contributes to this count, even though the overload group is a single field
254101095a5dSDimitry Andric   // list record.
254201095a5dSDimitry Andric   unsigned MemberCount = 0;
254301095a5dSDimitry Andric   ClassInfo Info = collectClassInfo(Ty);
2544044eb2f6SDimitry Andric   ContinuationRecordBuilder ContinuationBuilder;
2545044eb2f6SDimitry Andric   ContinuationBuilder.begin(ContinuationRecordKind::FieldList);
254601095a5dSDimitry Andric 
254701095a5dSDimitry Andric   // Create base classes.
254801095a5dSDimitry Andric   for (const DIDerivedType *I : Info.Inheritance) {
254901095a5dSDimitry Andric     if (I->getFlags() & DINode::FlagVirtual) {
255001095a5dSDimitry Andric       // Virtual base.
2551eb11fae6SDimitry Andric       unsigned VBPtrOffset = I->getVBPtrOffset();
255201095a5dSDimitry Andric       // FIXME: Despite the accessor name, the offset is really in bytes.
255301095a5dSDimitry Andric       unsigned VBTableIndex = I->getOffsetInBits() / 4;
2554b915e9e0SDimitry Andric       auto RecordKind = (I->getFlags() & DINode::FlagIndirectVirtualBase) == DINode::FlagIndirectVirtualBase
2555b915e9e0SDimitry Andric                             ? TypeRecordKind::IndirectVirtualBaseClass
2556b915e9e0SDimitry Andric                             : TypeRecordKind::VirtualBaseClass;
2557b915e9e0SDimitry Andric       VirtualBaseClassRecord VBCR(
2558b915e9e0SDimitry Andric           RecordKind, translateAccessFlags(Ty->getTag(), I->getFlags()),
255901095a5dSDimitry Andric           getTypeIndex(I->getBaseType()), getVBPTypeIndex(), VBPtrOffset,
2560b915e9e0SDimitry Andric           VBTableIndex);
2561b915e9e0SDimitry Andric 
2562044eb2f6SDimitry Andric       ContinuationBuilder.writeMemberType(VBCR);
2563eb11fae6SDimitry Andric       MemberCount++;
256401095a5dSDimitry Andric     } else {
256501095a5dSDimitry Andric       assert(I->getOffsetInBits() % 8 == 0 &&
256601095a5dSDimitry Andric              "bases must be on byte boundaries");
2567b915e9e0SDimitry Andric       BaseClassRecord BCR(translateAccessFlags(Ty->getTag(), I->getFlags()),
2568b915e9e0SDimitry Andric                           getTypeIndex(I->getBaseType()),
2569b915e9e0SDimitry Andric                           I->getOffsetInBits() / 8);
2570044eb2f6SDimitry Andric       ContinuationBuilder.writeMemberType(BCR);
2571eb11fae6SDimitry Andric       MemberCount++;
257201095a5dSDimitry Andric     }
257301095a5dSDimitry Andric   }
257401095a5dSDimitry Andric 
257501095a5dSDimitry Andric   // Create members.
257601095a5dSDimitry Andric   for (ClassInfo::MemberInfo &MemberInfo : Info.Members) {
257701095a5dSDimitry Andric     const DIDerivedType *Member = MemberInfo.MemberTypeNode;
257801095a5dSDimitry Andric     TypeIndex MemberBaseType = getTypeIndex(Member->getBaseType());
257901095a5dSDimitry Andric     StringRef MemberName = Member->getName();
258001095a5dSDimitry Andric     MemberAccess Access =
258101095a5dSDimitry Andric         translateAccessFlags(Ty->getTag(), Member->getFlags());
258201095a5dSDimitry Andric 
258301095a5dSDimitry Andric     if (Member->isStaticMember()) {
2584b915e9e0SDimitry Andric       StaticDataMemberRecord SDMR(Access, MemberBaseType, MemberName);
2585044eb2f6SDimitry Andric       ContinuationBuilder.writeMemberType(SDMR);
2586b915e9e0SDimitry Andric       MemberCount++;
2587b915e9e0SDimitry Andric       continue;
2588b915e9e0SDimitry Andric     }
2589b915e9e0SDimitry Andric 
2590b915e9e0SDimitry Andric     // Virtual function pointer member.
2591b915e9e0SDimitry Andric     if ((Member->getFlags() & DINode::FlagArtificial) &&
2592b1c73532SDimitry Andric         Member->getName().starts_with("_vptr$")) {
2593b915e9e0SDimitry Andric       VFPtrRecord VFPR(getTypeIndex(Member->getBaseType()));
2594044eb2f6SDimitry Andric       ContinuationBuilder.writeMemberType(VFPR);
259501095a5dSDimitry Andric       MemberCount++;
259601095a5dSDimitry Andric       continue;
259701095a5dSDimitry Andric     }
259801095a5dSDimitry Andric 
259901095a5dSDimitry Andric     // Data member.
260001095a5dSDimitry Andric     uint64_t MemberOffsetInBits =
260101095a5dSDimitry Andric         Member->getOffsetInBits() + MemberInfo.BaseOffset;
260201095a5dSDimitry Andric     if (Member->isBitField()) {
260301095a5dSDimitry Andric       uint64_t StartBitOffset = MemberOffsetInBits;
260401095a5dSDimitry Andric       if (const auto *CI =
260501095a5dSDimitry Andric               dyn_cast_or_null<ConstantInt>(Member->getStorageOffsetInBits())) {
260601095a5dSDimitry Andric         MemberOffsetInBits = CI->getZExtValue() + MemberInfo.BaseOffset;
260701095a5dSDimitry Andric       }
260801095a5dSDimitry Andric       StartBitOffset -= MemberOffsetInBits;
2609b915e9e0SDimitry Andric       BitFieldRecord BFR(MemberBaseType, Member->getSizeInBits(),
2610b915e9e0SDimitry Andric                          StartBitOffset);
2611044eb2f6SDimitry Andric       MemberBaseType = TypeTable.writeLeafType(BFR);
261201095a5dSDimitry Andric     }
261301095a5dSDimitry Andric     uint64_t MemberOffsetInBytes = MemberOffsetInBits / 8;
2614b915e9e0SDimitry Andric     DataMemberRecord DMR(Access, MemberBaseType, MemberOffsetInBytes,
2615b915e9e0SDimitry Andric                          MemberName);
2616044eb2f6SDimitry Andric     ContinuationBuilder.writeMemberType(DMR);
261701095a5dSDimitry Andric     MemberCount++;
261801095a5dSDimitry Andric   }
261901095a5dSDimitry Andric 
262001095a5dSDimitry Andric   // Create methods
262101095a5dSDimitry Andric   for (auto &MethodItr : Info.Methods) {
262201095a5dSDimitry Andric     StringRef Name = MethodItr.first->getString();
262301095a5dSDimitry Andric 
262401095a5dSDimitry Andric     std::vector<OneMethodRecord> Methods;
262501095a5dSDimitry Andric     for (const DISubprogram *SP : MethodItr.second) {
262601095a5dSDimitry Andric       TypeIndex MethodType = getMemberFunctionType(SP, Ty);
262701095a5dSDimitry Andric       bool Introduced = SP->getFlags() & DINode::FlagIntroducedVirtual;
262801095a5dSDimitry Andric 
262901095a5dSDimitry Andric       unsigned VFTableOffset = -1;
263001095a5dSDimitry Andric       if (Introduced)
263101095a5dSDimitry Andric         VFTableOffset = SP->getVirtualIndex() * getPointerSizeInBytes();
263201095a5dSDimitry Andric 
2633b915e9e0SDimitry Andric       Methods.push_back(OneMethodRecord(
2634b915e9e0SDimitry Andric           MethodType, translateAccessFlags(Ty->getTag(), SP->getFlags()),
2635b915e9e0SDimitry Andric           translateMethodKindFlags(SP, Introduced),
2636b915e9e0SDimitry Andric           translateMethodOptionFlags(SP), VFTableOffset, Name));
263701095a5dSDimitry Andric       MemberCount++;
263801095a5dSDimitry Andric     }
26397ab83427SDimitry Andric     assert(!Methods.empty() && "Empty methods map entry");
264001095a5dSDimitry Andric     if (Methods.size() == 1)
2641044eb2f6SDimitry Andric       ContinuationBuilder.writeMemberType(Methods[0]);
264201095a5dSDimitry Andric     else {
2643044eb2f6SDimitry Andric       // FIXME: Make this use its own ContinuationBuilder so that
2644044eb2f6SDimitry Andric       // MethodOverloadList can be split correctly.
2645b915e9e0SDimitry Andric       MethodOverloadListRecord MOLR(Methods);
2646044eb2f6SDimitry Andric       TypeIndex MethodList = TypeTable.writeLeafType(MOLR);
2647044eb2f6SDimitry Andric 
2648b915e9e0SDimitry Andric       OverloadedMethodRecord OMR(Methods.size(), MethodList, Name);
2649044eb2f6SDimitry Andric       ContinuationBuilder.writeMemberType(OMR);
265001095a5dSDimitry Andric     }
265101095a5dSDimitry Andric   }
265201095a5dSDimitry Andric 
265301095a5dSDimitry Andric   // Create nested classes.
2654044eb2f6SDimitry Andric   for (const DIType *Nested : Info.NestedTypes) {
2655e6d15924SDimitry Andric     NestedTypeRecord R(getTypeIndex(Nested), Nested->getName());
2656044eb2f6SDimitry Andric     ContinuationBuilder.writeMemberType(R);
265701095a5dSDimitry Andric     MemberCount++;
265801095a5dSDimitry Andric   }
265901095a5dSDimitry Andric 
2660044eb2f6SDimitry Andric   TypeIndex FieldTI = TypeTable.insertRecord(ContinuationBuilder);
2661b915e9e0SDimitry Andric   return std::make_tuple(FieldTI, Info.VShapeTI, MemberCount,
2662044eb2f6SDimitry Andric                          !Info.NestedTypes.empty());
266301095a5dSDimitry Andric }
266401095a5dSDimitry Andric 
getVBPTypeIndex()266501095a5dSDimitry Andric TypeIndex CodeViewDebug::getVBPTypeIndex() {
266601095a5dSDimitry Andric   if (!VBPType.getIndex()) {
266701095a5dSDimitry Andric     // Make a 'const int *' type.
266801095a5dSDimitry Andric     ModifierRecord MR(TypeIndex::Int32(), ModifierOptions::Const);
2669044eb2f6SDimitry Andric     TypeIndex ModifiedTI = TypeTable.writeLeafType(MR);
267001095a5dSDimitry Andric 
267101095a5dSDimitry Andric     PointerKind PK = getPointerSizeInBytes() == 8 ? PointerKind::Near64
267201095a5dSDimitry Andric                                                   : PointerKind::Near32;
267301095a5dSDimitry Andric     PointerMode PM = PointerMode::Pointer;
267401095a5dSDimitry Andric     PointerOptions PO = PointerOptions::None;
267501095a5dSDimitry Andric     PointerRecord PR(ModifiedTI, PK, PM, PO, getPointerSizeInBytes());
2676044eb2f6SDimitry Andric     VBPType = TypeTable.writeLeafType(PR);
267701095a5dSDimitry Andric   }
267801095a5dSDimitry Andric 
267901095a5dSDimitry Andric   return VBPType;
268001095a5dSDimitry Andric }
268101095a5dSDimitry Andric 
getTypeIndex(const DIType * Ty,const DIType * ClassTy)2682e6d15924SDimitry Andric TypeIndex CodeViewDebug::getTypeIndex(const DIType *Ty, const DIType *ClassTy) {
268301095a5dSDimitry Andric   // The null DIType is the void type. Don't try to hash it.
268401095a5dSDimitry Andric   if (!Ty)
268501095a5dSDimitry Andric     return TypeIndex::Void();
268601095a5dSDimitry Andric 
268701095a5dSDimitry Andric   // Check if we've already translated this type. Don't try to do a
268801095a5dSDimitry Andric   // get-or-create style insertion that caches the hash lookup across the
268901095a5dSDimitry Andric   // lowerType call. It will update the TypeIndices map.
269001095a5dSDimitry Andric   auto I = TypeIndices.find({Ty, ClassTy});
269101095a5dSDimitry Andric   if (I != TypeIndices.end())
269201095a5dSDimitry Andric     return I->second;
269301095a5dSDimitry Andric 
269401095a5dSDimitry Andric   TypeLoweringScope S(*this);
269501095a5dSDimitry Andric   TypeIndex TI = lowerType(Ty, ClassTy);
269601095a5dSDimitry Andric   return recordTypeIndexForDINode(Ty, TI, ClassTy);
269701095a5dSDimitry Andric }
269801095a5dSDimitry Andric 
2699d8e91e46SDimitry Andric codeview::TypeIndex
getTypeIndexForThisPtr(const DIDerivedType * PtrTy,const DISubroutineType * SubroutineTy)2700d8e91e46SDimitry Andric CodeViewDebug::getTypeIndexForThisPtr(const DIDerivedType *PtrTy,
2701d8e91e46SDimitry Andric                                       const DISubroutineType *SubroutineTy) {
2702d8e91e46SDimitry Andric   assert(PtrTy->getTag() == dwarf::DW_TAG_pointer_type &&
2703d8e91e46SDimitry Andric          "this type must be a pointer type");
2704d8e91e46SDimitry Andric 
2705d8e91e46SDimitry Andric   PointerOptions Options = PointerOptions::None;
2706d8e91e46SDimitry Andric   if (SubroutineTy->getFlags() & DINode::DIFlags::FlagLValueReference)
2707d8e91e46SDimitry Andric     Options = PointerOptions::LValueRefThisPointer;
2708d8e91e46SDimitry Andric   else if (SubroutineTy->getFlags() & DINode::DIFlags::FlagRValueReference)
2709d8e91e46SDimitry Andric     Options = PointerOptions::RValueRefThisPointer;
2710d8e91e46SDimitry Andric 
2711d8e91e46SDimitry Andric   // Check if we've already translated this type.  If there is no ref qualifier
2712d8e91e46SDimitry Andric   // on the function then we look up this pointer type with no associated class
2713d8e91e46SDimitry Andric   // so that the TypeIndex for the this pointer can be shared with the type
2714d8e91e46SDimitry Andric   // index for other pointers to this class type.  If there is a ref qualifier
2715d8e91e46SDimitry Andric   // then we lookup the pointer using the subroutine as the parent type.
2716d8e91e46SDimitry Andric   auto I = TypeIndices.find({PtrTy, SubroutineTy});
2717d8e91e46SDimitry Andric   if (I != TypeIndices.end())
2718d8e91e46SDimitry Andric     return I->second;
2719d8e91e46SDimitry Andric 
2720d8e91e46SDimitry Andric   TypeLoweringScope S(*this);
2721d8e91e46SDimitry Andric   TypeIndex TI = lowerTypePointer(PtrTy, Options);
2722d8e91e46SDimitry Andric   return recordTypeIndexForDINode(PtrTy, TI, SubroutineTy);
2723d8e91e46SDimitry Andric }
2724d8e91e46SDimitry Andric 
getTypeIndexForReferenceTo(const DIType * Ty)2725e6d15924SDimitry Andric TypeIndex CodeViewDebug::getTypeIndexForReferenceTo(const DIType *Ty) {
2726044eb2f6SDimitry Andric   PointerRecord PR(getTypeIndex(Ty),
2727044eb2f6SDimitry Andric                    getPointerSizeInBytes() == 8 ? PointerKind::Near64
2728044eb2f6SDimitry Andric                                                 : PointerKind::Near32,
2729044eb2f6SDimitry Andric                    PointerMode::LValueReference, PointerOptions::None,
2730044eb2f6SDimitry Andric                    Ty->getSizeInBits() / 8);
2731044eb2f6SDimitry Andric   return TypeTable.writeLeafType(PR);
2732044eb2f6SDimitry Andric }
2733044eb2f6SDimitry Andric 
getCompleteTypeIndex(const DIType * Ty)2734e6d15924SDimitry Andric TypeIndex CodeViewDebug::getCompleteTypeIndex(const DIType *Ty) {
273501095a5dSDimitry Andric   // The null DIType is the void type. Don't try to hash it.
273601095a5dSDimitry Andric   if (!Ty)
273701095a5dSDimitry Andric     return TypeIndex::Void();
273801095a5dSDimitry Andric 
2739d8e91e46SDimitry Andric   // Look through typedefs when getting the complete type index. Call
2740d8e91e46SDimitry Andric   // getTypeIndex on the typdef to ensure that any UDTs are accumulated and are
2741d8e91e46SDimitry Andric   // emitted only once.
2742d8e91e46SDimitry Andric   if (Ty->getTag() == dwarf::DW_TAG_typedef)
2743d8e91e46SDimitry Andric     (void)getTypeIndex(Ty);
2744d8e91e46SDimitry Andric   while (Ty->getTag() == dwarf::DW_TAG_typedef)
2745e6d15924SDimitry Andric     Ty = cast<DIDerivedType>(Ty)->getBaseType();
2746d8e91e46SDimitry Andric 
274701095a5dSDimitry Andric   // If this is a non-record type, the complete type index is the same as the
274801095a5dSDimitry Andric   // normal type index. Just call getTypeIndex.
274901095a5dSDimitry Andric   switch (Ty->getTag()) {
275001095a5dSDimitry Andric   case dwarf::DW_TAG_class_type:
275101095a5dSDimitry Andric   case dwarf::DW_TAG_structure_type:
275201095a5dSDimitry Andric   case dwarf::DW_TAG_union_type:
275301095a5dSDimitry Andric     break;
275401095a5dSDimitry Andric   default:
275501095a5dSDimitry Andric     return getTypeIndex(Ty);
275601095a5dSDimitry Andric   }
275701095a5dSDimitry Andric 
275801095a5dSDimitry Andric   const auto *CTy = cast<DICompositeType>(Ty);
275901095a5dSDimitry Andric 
276001095a5dSDimitry Andric   TypeLoweringScope S(*this);
276101095a5dSDimitry Andric 
276201095a5dSDimitry Andric   // Make sure the forward declaration is emitted first. It's unclear if this
276301095a5dSDimitry Andric   // is necessary, but MSVC does it, and we should follow suit until we can show
276401095a5dSDimitry Andric   // otherwise.
2765eb11fae6SDimitry Andric   // We only emit a forward declaration for named types.
2766eb11fae6SDimitry Andric   if (!CTy->getName().empty() || !CTy->getIdentifier().empty()) {
276701095a5dSDimitry Andric     TypeIndex FwdDeclTI = getTypeIndex(CTy);
276801095a5dSDimitry Andric 
2769eb11fae6SDimitry Andric     // Just use the forward decl if we don't have complete type info. This
2770eb11fae6SDimitry Andric     // might happen if the frontend is using modules and expects the complete
2771eb11fae6SDimitry Andric     // definition to be emitted elsewhere.
277201095a5dSDimitry Andric     if (CTy->isForwardDecl())
277301095a5dSDimitry Andric       return FwdDeclTI;
2774eb11fae6SDimitry Andric   }
277501095a5dSDimitry Andric 
2776e6d15924SDimitry Andric   // Check if we've already translated the complete record type.
2777e6d15924SDimitry Andric   // Insert the type with a null TypeIndex to signify that the type is currently
2778e6d15924SDimitry Andric   // being lowered.
2779e6d15924SDimitry Andric   auto InsertResult = CompleteTypeIndices.insert({CTy, TypeIndex()});
2780e6d15924SDimitry Andric   if (!InsertResult.second)
2781e6d15924SDimitry Andric     return InsertResult.first->second;
2782e6d15924SDimitry Andric 
278301095a5dSDimitry Andric   TypeIndex TI;
278401095a5dSDimitry Andric   switch (CTy->getTag()) {
278501095a5dSDimitry Andric   case dwarf::DW_TAG_class_type:
278601095a5dSDimitry Andric   case dwarf::DW_TAG_structure_type:
278701095a5dSDimitry Andric     TI = lowerCompleteTypeClass(CTy);
278801095a5dSDimitry Andric     break;
278901095a5dSDimitry Andric   case dwarf::DW_TAG_union_type:
279001095a5dSDimitry Andric     TI = lowerCompleteTypeUnion(CTy);
279101095a5dSDimitry Andric     break;
279201095a5dSDimitry Andric   default:
279301095a5dSDimitry Andric     llvm_unreachable("not a record");
279401095a5dSDimitry Andric   }
279501095a5dSDimitry Andric 
2796eb11fae6SDimitry Andric   // Update the type index associated with this CompositeType.  This cannot
2797eb11fae6SDimitry Andric   // use the 'InsertResult' iterator above because it is potentially
2798eb11fae6SDimitry Andric   // invalidated by map insertions which can occur while lowering the class
2799eb11fae6SDimitry Andric   // type above.
2800eb11fae6SDimitry Andric   CompleteTypeIndices[CTy] = TI;
280101095a5dSDimitry Andric   return TI;
280201095a5dSDimitry Andric }
280301095a5dSDimitry Andric 
280401095a5dSDimitry Andric /// Emit all the deferred complete record types. Try to do this in FIFO order,
280501095a5dSDimitry Andric /// and do this until fixpoint, as each complete record type typically
280601095a5dSDimitry Andric /// references
280701095a5dSDimitry Andric /// many other record types.
emitDeferredCompleteTypes()280801095a5dSDimitry Andric void CodeViewDebug::emitDeferredCompleteTypes() {
280901095a5dSDimitry Andric   SmallVector<const DICompositeType *, 4> TypesToEmit;
281001095a5dSDimitry Andric   while (!DeferredCompleteTypes.empty()) {
281101095a5dSDimitry Andric     std::swap(DeferredCompleteTypes, TypesToEmit);
281201095a5dSDimitry Andric     for (const DICompositeType *RecordTy : TypesToEmit)
281301095a5dSDimitry Andric       getCompleteTypeIndex(RecordTy);
281401095a5dSDimitry Andric     TypesToEmit.clear();
281501095a5dSDimitry Andric   }
281601095a5dSDimitry Andric }
281701095a5dSDimitry Andric 
emitLocalVariableList(const FunctionInfo & FI,ArrayRef<LocalVariable> Locals)2818d8e91e46SDimitry Andric void CodeViewDebug::emitLocalVariableList(const FunctionInfo &FI,
2819d8e91e46SDimitry Andric                                           ArrayRef<LocalVariable> Locals) {
282001095a5dSDimitry Andric   // Get the sorted list of parameters and emit them first.
282101095a5dSDimitry Andric   SmallVector<const LocalVariable *, 6> Params;
282201095a5dSDimitry Andric   for (const LocalVariable &L : Locals)
282301095a5dSDimitry Andric     if (L.DIVar->isParameter())
282401095a5dSDimitry Andric       Params.push_back(&L);
2825d8e91e46SDimitry Andric   llvm::sort(Params, [](const LocalVariable *L, const LocalVariable *R) {
282601095a5dSDimitry Andric     return L->DIVar->getArg() < R->DIVar->getArg();
282701095a5dSDimitry Andric   });
282801095a5dSDimitry Andric   for (const LocalVariable *L : Params)
2829d8e91e46SDimitry Andric     emitLocalVariable(FI, *L);
283001095a5dSDimitry Andric 
283101095a5dSDimitry Andric   // Next emit all non-parameters in the order that we found them.
2832e3b55780SDimitry Andric   for (const LocalVariable &L : Locals) {
2833e3b55780SDimitry Andric     if (!L.DIVar->isParameter()) {
2834e3b55780SDimitry Andric       if (L.ConstantValue) {
2835e3b55780SDimitry Andric         // If ConstantValue is set we will emit it as a S_CONSTANT instead of a
2836e3b55780SDimitry Andric         // S_LOCAL in order to be able to represent it at all.
2837e3b55780SDimitry Andric         const DIType *Ty = L.DIVar->getType();
2838e3b55780SDimitry Andric         APSInt Val(*L.ConstantValue);
2839e3b55780SDimitry Andric         emitConstantSymbolRecord(Ty, Val, std::string(L.DIVar->getName()));
2840e3b55780SDimitry Andric       } else {
2841d8e91e46SDimitry Andric         emitLocalVariable(FI, L);
284201095a5dSDimitry Andric       }
2843e3b55780SDimitry Andric     }
2844e3b55780SDimitry Andric   }
2845e3b55780SDimitry Andric }
284601095a5dSDimitry Andric 
emitLocalVariable(const FunctionInfo & FI,const LocalVariable & Var)2847d8e91e46SDimitry Andric void CodeViewDebug::emitLocalVariable(const FunctionInfo &FI,
2848d8e91e46SDimitry Andric                                       const LocalVariable &Var) {
2849d8e91e46SDimitry Andric   // LocalSym record, see SymbolRecord.h for more info.
2850d8e91e46SDimitry Andric   MCSymbol *LocalEnd = beginSymbolRecord(SymbolKind::S_LOCAL);
285101095a5dSDimitry Andric 
285201095a5dSDimitry Andric   LocalSymFlags Flags = LocalSymFlags::None;
285301095a5dSDimitry Andric   if (Var.DIVar->isParameter())
285401095a5dSDimitry Andric     Flags |= LocalSymFlags::IsParameter;
285501095a5dSDimitry Andric   if (Var.DefRanges.empty())
285601095a5dSDimitry Andric     Flags |= LocalSymFlags::IsOptimizedOut;
285701095a5dSDimitry Andric 
285801095a5dSDimitry Andric   OS.AddComment("TypeIndex");
2859044eb2f6SDimitry Andric   TypeIndex TI = Var.UseReferenceType
2860044eb2f6SDimitry Andric                      ? getTypeIndexForReferenceTo(Var.DIVar->getType())
2861044eb2f6SDimitry Andric                      : getCompleteTypeIndex(Var.DIVar->getType());
2862cfca06d7SDimitry Andric   OS.emitInt32(TI.getIndex());
286301095a5dSDimitry Andric   OS.AddComment("Flags");
2864cfca06d7SDimitry Andric   OS.emitInt16(static_cast<uint16_t>(Flags));
286501095a5dSDimitry Andric   // Truncate the name so we won't overflow the record length field.
286601095a5dSDimitry Andric   emitNullTerminatedSymbolName(OS, Var.DIVar->getName());
2867d8e91e46SDimitry Andric   endSymbolRecord(LocalEnd);
286801095a5dSDimitry Andric 
286901095a5dSDimitry Andric   // Calculate the on disk prefix of the appropriate def range record. The
287001095a5dSDimitry Andric   // records and on disk formats are described in SymbolRecords.h. BytePrefix
287101095a5dSDimitry Andric   // should be big enough to hold all forms without memory allocation.
287201095a5dSDimitry Andric   SmallString<20> BytePrefix;
2873145449b1SDimitry Andric   for (const auto &Pair : Var.DefRanges) {
2874145449b1SDimitry Andric     LocalVarDef DefRange = Pair.first;
2875145449b1SDimitry Andric     const auto &Ranges = Pair.second;
287601095a5dSDimitry Andric     BytePrefix.clear();
287701095a5dSDimitry Andric     if (DefRange.InMemory) {
2878d8e91e46SDimitry Andric       int Offset = DefRange.DataOffset;
2879d8e91e46SDimitry Andric       unsigned Reg = DefRange.CVRegister;
2880d8e91e46SDimitry Andric 
2881d8e91e46SDimitry Andric       // 32-bit x86 call sequences often use PUSH instructions, which disrupt
2882d8e91e46SDimitry Andric       // ESP-relative offsets. Use the virtual frame pointer, VFRAME or $T0,
2883d8e91e46SDimitry Andric       // instead. In frames without stack realignment, $T0 will be the CFA.
2884d8e91e46SDimitry Andric       if (RegisterId(Reg) == RegisterId::ESP) {
2885d8e91e46SDimitry Andric         Reg = unsigned(RegisterId::VFRAME);
2886d8e91e46SDimitry Andric         Offset += FI.OffsetAdjustment;
2887d8e91e46SDimitry Andric       }
2888d8e91e46SDimitry Andric 
2889d8e91e46SDimitry Andric       // If we can use the chosen frame pointer for the frame and this isn't a
2890d8e91e46SDimitry Andric       // sliced aggregate, use the smaller S_DEFRANGE_FRAMEPOINTER_REL record.
2891d8e91e46SDimitry Andric       // Otherwise, use S_DEFRANGE_REGISTER_REL.
2892d8e91e46SDimitry Andric       EncodedFramePtrReg EncFP = encodeFramePtrReg(RegisterId(Reg), TheCPU);
2893d8e91e46SDimitry Andric       if (!DefRange.IsSubfield && EncFP != EncodedFramePtrReg::None &&
2894d8e91e46SDimitry Andric           (bool(Flags & LocalSymFlags::IsParameter)
2895d8e91e46SDimitry Andric                ? (EncFP == FI.EncodedParamFramePtrReg)
2896d8e91e46SDimitry Andric                : (EncFP == FI.EncodedLocalFramePtrReg))) {
28971d5ae102SDimitry Andric         DefRangeFramePointerRelHeader DRHdr;
28981d5ae102SDimitry Andric         DRHdr.Offset = Offset;
2899145449b1SDimitry Andric         OS.emitCVDefRangeDirective(Ranges, DRHdr);
2900d8e91e46SDimitry Andric       } else {
2901b915e9e0SDimitry Andric         uint16_t RegRelFlags = 0;
2902b915e9e0SDimitry Andric         if (DefRange.IsSubfield) {
2903b915e9e0SDimitry Andric           RegRelFlags = DefRangeRegisterRelSym::IsSubfieldFlag |
2904b915e9e0SDimitry Andric                         (DefRange.StructOffset
2905b915e9e0SDimitry Andric                          << DefRangeRegisterRelSym::OffsetInParentShift);
2906b915e9e0SDimitry Andric         }
29071d5ae102SDimitry Andric         DefRangeRegisterRelHeader DRHdr;
2908d8e91e46SDimitry Andric         DRHdr.Register = Reg;
2909d8e91e46SDimitry Andric         DRHdr.Flags = RegRelFlags;
2910d8e91e46SDimitry Andric         DRHdr.BasePointerOffset = Offset;
2911145449b1SDimitry Andric         OS.emitCVDefRangeDirective(Ranges, DRHdr);
2912d8e91e46SDimitry Andric       }
291301095a5dSDimitry Andric     } else {
291401095a5dSDimitry Andric       assert(DefRange.DataOffset == 0 && "unexpected offset into register");
2915b915e9e0SDimitry Andric       if (DefRange.IsSubfield) {
29161d5ae102SDimitry Andric         DefRangeSubfieldRegisterHeader DRHdr;
2917d8e91e46SDimitry Andric         DRHdr.Register = DefRange.CVRegister;
2918d8e91e46SDimitry Andric         DRHdr.MayHaveNoName = 0;
2919d8e91e46SDimitry Andric         DRHdr.OffsetInParent = DefRange.StructOffset;
2920145449b1SDimitry Andric         OS.emitCVDefRangeDirective(Ranges, DRHdr);
2921b915e9e0SDimitry Andric       } else {
29221d5ae102SDimitry Andric         DefRangeRegisterHeader DRHdr;
2923d8e91e46SDimitry Andric         DRHdr.Register = DefRange.CVRegister;
2924d8e91e46SDimitry Andric         DRHdr.MayHaveNoName = 0;
2925145449b1SDimitry Andric         OS.emitCVDefRangeDirective(Ranges, DRHdr);
2926b915e9e0SDimitry Andric       }
292701095a5dSDimitry Andric     }
292801095a5dSDimitry Andric   }
292901095a5dSDimitry Andric }
293001095a5dSDimitry Andric 
emitLexicalBlockList(ArrayRef<LexicalBlock * > Blocks,const FunctionInfo & FI)2931eb11fae6SDimitry Andric void CodeViewDebug::emitLexicalBlockList(ArrayRef<LexicalBlock *> Blocks,
2932eb11fae6SDimitry Andric                                          const FunctionInfo& FI) {
2933eb11fae6SDimitry Andric   for (LexicalBlock *Block : Blocks)
2934eb11fae6SDimitry Andric     emitLexicalBlock(*Block, FI);
2935eb11fae6SDimitry Andric }
2936eb11fae6SDimitry Andric 
2937eb11fae6SDimitry Andric /// Emit an S_BLOCK32 and S_END record pair delimiting the contents of a
2938eb11fae6SDimitry Andric /// lexical block scope.
emitLexicalBlock(const LexicalBlock & Block,const FunctionInfo & FI)2939eb11fae6SDimitry Andric void CodeViewDebug::emitLexicalBlock(const LexicalBlock &Block,
2940eb11fae6SDimitry Andric                                      const FunctionInfo& FI) {
2941d8e91e46SDimitry Andric   MCSymbol *RecordEnd = beginSymbolRecord(SymbolKind::S_BLOCK32);
2942eb11fae6SDimitry Andric   OS.AddComment("PtrParent");
2943cfca06d7SDimitry Andric   OS.emitInt32(0); // PtrParent
2944eb11fae6SDimitry Andric   OS.AddComment("PtrEnd");
2945cfca06d7SDimitry Andric   OS.emitInt32(0); // PtrEnd
2946eb11fae6SDimitry Andric   OS.AddComment("Code size");
2947eb11fae6SDimitry Andric   OS.emitAbsoluteSymbolDiff(Block.End, Block.Begin, 4);   // Code Size
2948eb11fae6SDimitry Andric   OS.AddComment("Function section relative address");
2949145449b1SDimitry Andric   OS.emitCOFFSecRel32(Block.Begin, /*Offset=*/0); // Func Offset
2950eb11fae6SDimitry Andric   OS.AddComment("Function section index");
2951145449b1SDimitry Andric   OS.emitCOFFSectionIndex(FI.Begin); // Func Symbol
2952eb11fae6SDimitry Andric   OS.AddComment("Lexical block name");
2953eb11fae6SDimitry Andric   emitNullTerminatedSymbolName(OS, Block.Name);           // Name
2954d8e91e46SDimitry Andric   endSymbolRecord(RecordEnd);
2955eb11fae6SDimitry Andric 
2956eb11fae6SDimitry Andric   // Emit variables local to this lexical block.
2957d8e91e46SDimitry Andric   emitLocalVariableList(FI, Block.Locals);
2958d8e91e46SDimitry Andric   emitGlobalVariableList(Block.Globals);
2959eb11fae6SDimitry Andric 
2960eb11fae6SDimitry Andric   // Emit lexical blocks contained within this block.
2961eb11fae6SDimitry Andric   emitLexicalBlockList(Block.Children, FI);
2962eb11fae6SDimitry Andric 
2963eb11fae6SDimitry Andric   // Close the lexical block scope.
2964d8e91e46SDimitry Andric   emitEndSymbolRecord(SymbolKind::S_END);
2965eb11fae6SDimitry Andric }
2966eb11fae6SDimitry Andric 
2967eb11fae6SDimitry Andric /// Convenience routine for collecting lexical block information for a list
2968eb11fae6SDimitry Andric /// of lexical scopes.
collectLexicalBlockInfo(SmallVectorImpl<LexicalScope * > & Scopes,SmallVectorImpl<LexicalBlock * > & Blocks,SmallVectorImpl<LocalVariable> & Locals,SmallVectorImpl<CVGlobalVariable> & Globals)2969eb11fae6SDimitry Andric void CodeViewDebug::collectLexicalBlockInfo(
2970eb11fae6SDimitry Andric         SmallVectorImpl<LexicalScope *> &Scopes,
2971eb11fae6SDimitry Andric         SmallVectorImpl<LexicalBlock *> &Blocks,
2972d8e91e46SDimitry Andric         SmallVectorImpl<LocalVariable> &Locals,
2973d8e91e46SDimitry Andric         SmallVectorImpl<CVGlobalVariable> &Globals) {
2974eb11fae6SDimitry Andric   for (LexicalScope *Scope : Scopes)
2975d8e91e46SDimitry Andric     collectLexicalBlockInfo(*Scope, Blocks, Locals, Globals);
2976eb11fae6SDimitry Andric }
2977eb11fae6SDimitry Andric 
2978eb11fae6SDimitry Andric /// Populate the lexical blocks and local variable lists of the parent with
2979eb11fae6SDimitry Andric /// information about the specified lexical scope.
collectLexicalBlockInfo(LexicalScope & Scope,SmallVectorImpl<LexicalBlock * > & ParentBlocks,SmallVectorImpl<LocalVariable> & ParentLocals,SmallVectorImpl<CVGlobalVariable> & ParentGlobals)2980eb11fae6SDimitry Andric void CodeViewDebug::collectLexicalBlockInfo(
2981eb11fae6SDimitry Andric     LexicalScope &Scope,
2982eb11fae6SDimitry Andric     SmallVectorImpl<LexicalBlock *> &ParentBlocks,
2983d8e91e46SDimitry Andric     SmallVectorImpl<LocalVariable> &ParentLocals,
2984d8e91e46SDimitry Andric     SmallVectorImpl<CVGlobalVariable> &ParentGlobals) {
2985eb11fae6SDimitry Andric   if (Scope.isAbstractScope())
2986eb11fae6SDimitry Andric     return;
2987eb11fae6SDimitry Andric 
2988d8e91e46SDimitry Andric   // Gather information about the lexical scope including local variables,
2989d8e91e46SDimitry Andric   // global variables, and address ranges.
2990d8e91e46SDimitry Andric   bool IgnoreScope = false;
2991d8e91e46SDimitry Andric   auto LI = ScopeVariables.find(&Scope);
2992d8e91e46SDimitry Andric   SmallVectorImpl<LocalVariable> *Locals =
2993d8e91e46SDimitry Andric       LI != ScopeVariables.end() ? &LI->second : nullptr;
2994d8e91e46SDimitry Andric   auto GI = ScopeGlobals.find(Scope.getScopeNode());
2995d8e91e46SDimitry Andric   SmallVectorImpl<CVGlobalVariable> *Globals =
2996d8e91e46SDimitry Andric       GI != ScopeGlobals.end() ? GI->second.get() : nullptr;
2997eb11fae6SDimitry Andric   const DILexicalBlock *DILB = dyn_cast<DILexicalBlock>(Scope.getScopeNode());
2998eb11fae6SDimitry Andric   const SmallVectorImpl<InsnRange> &Ranges = Scope.getRanges();
2999d8e91e46SDimitry Andric 
3000d8e91e46SDimitry Andric   // Ignore lexical scopes which do not contain variables.
3001d8e91e46SDimitry Andric   if (!Locals && !Globals)
3002d8e91e46SDimitry Andric     IgnoreScope = true;
3003d8e91e46SDimitry Andric 
3004d8e91e46SDimitry Andric   // Ignore lexical scopes which are not lexical blocks.
3005d8e91e46SDimitry Andric   if (!DILB)
3006d8e91e46SDimitry Andric     IgnoreScope = true;
3007d8e91e46SDimitry Andric 
3008d8e91e46SDimitry Andric   // Ignore scopes which have too many address ranges to represent in the
3009d8e91e46SDimitry Andric   // current CodeView format or do not have a valid address range.
3010eb11fae6SDimitry Andric   //
3011eb11fae6SDimitry Andric   // For lexical scopes with multiple address ranges you may be tempted to
3012eb11fae6SDimitry Andric   // construct a single range covering every instruction where the block is
3013eb11fae6SDimitry Andric   // live and everything in between.  Unfortunately, Visual Studio only
3014eb11fae6SDimitry Andric   // displays variables from the first matching lexical block scope.  If the
3015eb11fae6SDimitry Andric   // first lexical block contains exception handling code or cold code which
3016eb11fae6SDimitry Andric   // is moved to the bottom of the routine creating a single range covering
3017eb11fae6SDimitry Andric   // nearly the entire routine, then it will hide all other lexical blocks
3018eb11fae6SDimitry Andric   // and the variables they contain.
3019d8e91e46SDimitry Andric   if (Ranges.size() != 1 || !getLabelAfterInsn(Ranges.front().second))
3020d8e91e46SDimitry Andric     IgnoreScope = true;
3021d8e91e46SDimitry Andric 
3022d8e91e46SDimitry Andric   if (IgnoreScope) {
3023d8e91e46SDimitry Andric     // This scope can be safely ignored and eliminating it will reduce the
3024d8e91e46SDimitry Andric     // size of the debug information. Be sure to collect any variable and scope
3025d8e91e46SDimitry Andric     // information from the this scope or any of its children and collapse them
3026d8e91e46SDimitry Andric     // into the parent scope.
3027d8e91e46SDimitry Andric     if (Locals)
3028d8e91e46SDimitry Andric       ParentLocals.append(Locals->begin(), Locals->end());
3029d8e91e46SDimitry Andric     if (Globals)
3030d8e91e46SDimitry Andric       ParentGlobals.append(Globals->begin(), Globals->end());
3031d8e91e46SDimitry Andric     collectLexicalBlockInfo(Scope.getChildren(),
3032d8e91e46SDimitry Andric                             ParentBlocks,
3033d8e91e46SDimitry Andric                             ParentLocals,
3034d8e91e46SDimitry Andric                             ParentGlobals);
3035eb11fae6SDimitry Andric     return;
3036eb11fae6SDimitry Andric   }
3037eb11fae6SDimitry Andric 
3038eb11fae6SDimitry Andric   // Create a new CodeView lexical block for this lexical scope.  If we've
3039eb11fae6SDimitry Andric   // seen this DILexicalBlock before then the scope tree is malformed and
3040eb11fae6SDimitry Andric   // we can handle this gracefully by not processing it a second time.
3041eb11fae6SDimitry Andric   auto BlockInsertion = CurFn->LexicalBlocks.insert({DILB, LexicalBlock()});
3042eb11fae6SDimitry Andric   if (!BlockInsertion.second)
3043eb11fae6SDimitry Andric     return;
3044eb11fae6SDimitry Andric 
3045b1c73532SDimitry Andric   // Create a lexical block containing the variables and collect the
3046d8e91e46SDimitry Andric   // lexical block information for the children.
3047eb11fae6SDimitry Andric   const InsnRange &Range = Ranges.front();
3048eb11fae6SDimitry Andric   assert(Range.first && Range.second);
3049eb11fae6SDimitry Andric   LexicalBlock &Block = BlockInsertion.first->second;
3050eb11fae6SDimitry Andric   Block.Begin = getLabelBeforeInsn(Range.first);
3051eb11fae6SDimitry Andric   Block.End = getLabelAfterInsn(Range.second);
3052eb11fae6SDimitry Andric   assert(Block.Begin && "missing label for scope begin");
3053eb11fae6SDimitry Andric   assert(Block.End && "missing label for scope end");
3054eb11fae6SDimitry Andric   Block.Name = DILB->getName();
3055d8e91e46SDimitry Andric   if (Locals)
3056d8e91e46SDimitry Andric     Block.Locals = std::move(*Locals);
3057d8e91e46SDimitry Andric   if (Globals)
3058d8e91e46SDimitry Andric     Block.Globals = std::move(*Globals);
3059eb11fae6SDimitry Andric   ParentBlocks.push_back(&Block);
3060d8e91e46SDimitry Andric   collectLexicalBlockInfo(Scope.getChildren(),
3061d8e91e46SDimitry Andric                           Block.Children,
3062d8e91e46SDimitry Andric                           Block.Locals,
3063d8e91e46SDimitry Andric                           Block.Globals);
3064eb11fae6SDimitry Andric }
3065eb11fae6SDimitry Andric 
endFunctionImpl(const MachineFunction * MF)306671d5a254SDimitry Andric void CodeViewDebug::endFunctionImpl(const MachineFunction *MF) {
3067044eb2f6SDimitry Andric   const Function &GV = MF->getFunction();
3068044eb2f6SDimitry Andric   assert(FnDebugInfo.count(&GV));
3069eb11fae6SDimitry Andric   assert(CurFn == FnDebugInfo[&GV].get());
307001095a5dSDimitry Andric 
3071044eb2f6SDimitry Andric   collectVariableInfo(GV.getSubprogram());
307201095a5dSDimitry Andric 
3073eb11fae6SDimitry Andric   // Build the lexical block structure to emit for this routine.
3074eb11fae6SDimitry Andric   if (LexicalScope *CFS = LScopes.getCurrentFunctionScope())
3075d8e91e46SDimitry Andric     collectLexicalBlockInfo(*CFS,
3076d8e91e46SDimitry Andric                             CurFn->ChildBlocks,
3077d8e91e46SDimitry Andric                             CurFn->Locals,
3078d8e91e46SDimitry Andric                             CurFn->Globals);
3079eb11fae6SDimitry Andric 
3080eb11fae6SDimitry Andric   // Clear the scope and variable information from the map which will not be
3081eb11fae6SDimitry Andric   // valid after we have finished processing this routine.  This also prepares
3082eb11fae6SDimitry Andric   // the map for the subsequent routine.
3083eb11fae6SDimitry Andric   ScopeVariables.clear();
3084eb11fae6SDimitry Andric 
308501095a5dSDimitry Andric   // Don't emit anything if we don't have any line tables.
3086eb11fae6SDimitry Andric   // Thunks are compiler-generated and probably won't have source correlation.
3087eb11fae6SDimitry Andric   if (!CurFn->HaveLineInfo && !GV.getSubprogram()->isThunk()) {
3088044eb2f6SDimitry Andric     FnDebugInfo.erase(&GV);
308901095a5dSDimitry Andric     CurFn = nullptr;
309001095a5dSDimitry Andric     return;
309101095a5dSDimitry Andric   }
309201095a5dSDimitry Andric 
3093706b4fc4SDimitry Andric   // Find heap alloc sites and add to list.
3094706b4fc4SDimitry Andric   for (const auto &MBB : *MF) {
3095706b4fc4SDimitry Andric     for (const auto &MI : MBB) {
3096706b4fc4SDimitry Andric       if (MDNode *MD = MI.getHeapAllocMarker()) {
3097706b4fc4SDimitry Andric         CurFn->HeapAllocSites.push_back(std::make_tuple(getLabelBeforeInsn(&MI),
3098706b4fc4SDimitry Andric                                                         getLabelAfterInsn(&MI),
3099706b4fc4SDimitry Andric                                                         dyn_cast<DIType>(MD)));
3100706b4fc4SDimitry Andric       }
3101706b4fc4SDimitry Andric     }
3102706b4fc4SDimitry Andric   }
3103706b4fc4SDimitry Andric 
3104b1c73532SDimitry Andric   bool isThumb = Triple(MMI->getModule()->getTargetTriple()).getArch() ==
3105b1c73532SDimitry Andric                  llvm::Triple::ArchType::thumb;
3106b1c73532SDimitry Andric   collectDebugInfoForJumpTables(MF, isThumb);
3107b1c73532SDimitry Andric 
3108044eb2f6SDimitry Andric   CurFn->Annotations = MF->getCodeViewAnnotations();
3109044eb2f6SDimitry Andric 
311001095a5dSDimitry Andric   CurFn->End = Asm->getFunctionEnd();
311101095a5dSDimitry Andric 
311201095a5dSDimitry Andric   CurFn = nullptr;
311301095a5dSDimitry Andric }
311401095a5dSDimitry Andric 
31151d5ae102SDimitry Andric // Usable locations are valid with non-zero line numbers. A line number of zero
31161d5ae102SDimitry Andric // corresponds to optimized code that doesn't have a distinct source location.
31171d5ae102SDimitry Andric // In this case, we try to use the previous or next source location depending on
31181d5ae102SDimitry Andric // the context.
isUsableDebugLoc(DebugLoc DL)31191d5ae102SDimitry Andric static bool isUsableDebugLoc(DebugLoc DL) {
31201d5ae102SDimitry Andric   return DL && DL.getLine() != 0;
31211d5ae102SDimitry Andric }
31221d5ae102SDimitry Andric 
beginInstruction(const MachineInstr * MI)312301095a5dSDimitry Andric void CodeViewDebug::beginInstruction(const MachineInstr *MI) {
312401095a5dSDimitry Andric   DebugHandlerBase::beginInstruction(MI);
312501095a5dSDimitry Andric 
3126eb11fae6SDimitry Andric   // Ignore DBG_VALUE and DBG_LABEL locations and function prologue.
3127eb11fae6SDimitry Andric   if (!Asm || !CurFn || MI->isDebugInstr() ||
3128a7fe922bSDimitry Andric       MI->getFlag(MachineInstr::FrameSetup))
312901095a5dSDimitry Andric     return;
31309df3605dSDimitry Andric 
31319df3605dSDimitry Andric   // If the first instruction of a new MBB has no location, find the first
31329df3605dSDimitry Andric   // instruction with a location and use that.
313301095a5dSDimitry Andric   DebugLoc DL = MI->getDebugLoc();
31341d5ae102SDimitry Andric   if (!isUsableDebugLoc(DL) && MI->getParent() != PrevInstBB) {
31359df3605dSDimitry Andric     for (const auto &NextMI : *MI->getParent()) {
3136eb11fae6SDimitry Andric       if (NextMI.isDebugInstr())
3137044eb2f6SDimitry Andric         continue;
31389df3605dSDimitry Andric       DL = NextMI.getDebugLoc();
31391d5ae102SDimitry Andric       if (isUsableDebugLoc(DL))
31409df3605dSDimitry Andric         break;
31419df3605dSDimitry Andric     }
31421d5ae102SDimitry Andric     // FIXME: Handle the case where the BB has no valid locations. This would
31431d5ae102SDimitry Andric     // probably require doing a real dataflow analysis.
31449df3605dSDimitry Andric   }
31459df3605dSDimitry Andric   PrevInstBB = MI->getParent();
31469df3605dSDimitry Andric 
31479df3605dSDimitry Andric   // If we still don't have a debug location, don't record a location.
31481d5ae102SDimitry Andric   if (!isUsableDebugLoc(DL))
314901095a5dSDimitry Andric     return;
31509df3605dSDimitry Andric 
315101095a5dSDimitry Andric   maybeRecordLocation(DL, Asm->MF);
315201095a5dSDimitry Andric }
315301095a5dSDimitry Andric 
beginCVSubsection(DebugSubsectionKind Kind)3154ee2f195dSDimitry Andric MCSymbol *CodeViewDebug::beginCVSubsection(DebugSubsectionKind Kind) {
315501095a5dSDimitry Andric   MCSymbol *BeginLabel = MMI->getContext().createTempSymbol(),
315601095a5dSDimitry Andric            *EndLabel = MMI->getContext().createTempSymbol();
3157cfca06d7SDimitry Andric   OS.emitInt32(unsigned(Kind));
315801095a5dSDimitry Andric   OS.AddComment("Subsection size");
315901095a5dSDimitry Andric   OS.emitAbsoluteSymbolDiff(EndLabel, BeginLabel, 4);
3160cfca06d7SDimitry Andric   OS.emitLabel(BeginLabel);
316101095a5dSDimitry Andric   return EndLabel;
316201095a5dSDimitry Andric }
316301095a5dSDimitry Andric 
endCVSubsection(MCSymbol * EndLabel)316401095a5dSDimitry Andric void CodeViewDebug::endCVSubsection(MCSymbol *EndLabel) {
3165cfca06d7SDimitry Andric   OS.emitLabel(EndLabel);
316601095a5dSDimitry Andric   // Every subsection must be aligned to a 4-byte boundary.
3167e3b55780SDimitry Andric   OS.emitValueToAlignment(Align(4));
316801095a5dSDimitry Andric }
316901095a5dSDimitry Andric 
getSymbolName(SymbolKind SymKind)3170d8e91e46SDimitry Andric static StringRef getSymbolName(SymbolKind SymKind) {
3171d8e91e46SDimitry Andric   for (const EnumEntry<SymbolKind> &EE : getSymbolTypeNames())
3172d8e91e46SDimitry Andric     if (EE.Value == SymKind)
3173d8e91e46SDimitry Andric       return EE.Name;
3174d8e91e46SDimitry Andric   return "";
3175d8e91e46SDimitry Andric }
3176d8e91e46SDimitry Andric 
beginSymbolRecord(SymbolKind SymKind)3177d8e91e46SDimitry Andric MCSymbol *CodeViewDebug::beginSymbolRecord(SymbolKind SymKind) {
3178d8e91e46SDimitry Andric   MCSymbol *BeginLabel = MMI->getContext().createTempSymbol(),
3179d8e91e46SDimitry Andric            *EndLabel = MMI->getContext().createTempSymbol();
3180d8e91e46SDimitry Andric   OS.AddComment("Record length");
3181d8e91e46SDimitry Andric   OS.emitAbsoluteSymbolDiff(EndLabel, BeginLabel, 2);
3182cfca06d7SDimitry Andric   OS.emitLabel(BeginLabel);
3183d8e91e46SDimitry Andric   if (OS.isVerboseAsm())
3184d8e91e46SDimitry Andric     OS.AddComment("Record kind: " + getSymbolName(SymKind));
3185cfca06d7SDimitry Andric   OS.emitInt16(unsigned(SymKind));
3186d8e91e46SDimitry Andric   return EndLabel;
3187d8e91e46SDimitry Andric }
3188d8e91e46SDimitry Andric 
endSymbolRecord(MCSymbol * SymEnd)3189d8e91e46SDimitry Andric void CodeViewDebug::endSymbolRecord(MCSymbol *SymEnd) {
3190d8e91e46SDimitry Andric   // MSVC does not pad out symbol records to four bytes, but LLVM does to avoid
3191d8e91e46SDimitry Andric   // an extra copy of every symbol record in LLD. This increases object file
3192d8e91e46SDimitry Andric   // size by less than 1% in the clang build, and is compatible with the Visual
3193d8e91e46SDimitry Andric   // C++ linker.
3194e3b55780SDimitry Andric   OS.emitValueToAlignment(Align(4));
3195cfca06d7SDimitry Andric   OS.emitLabel(SymEnd);
3196d8e91e46SDimitry Andric }
3197d8e91e46SDimitry Andric 
emitEndSymbolRecord(SymbolKind EndKind)3198d8e91e46SDimitry Andric void CodeViewDebug::emitEndSymbolRecord(SymbolKind EndKind) {
3199d8e91e46SDimitry Andric   OS.AddComment("Record length");
3200cfca06d7SDimitry Andric   OS.emitInt16(2);
3201d8e91e46SDimitry Andric   if (OS.isVerboseAsm())
3202d8e91e46SDimitry Andric     OS.AddComment("Record kind: " + getSymbolName(EndKind));
3203cfca06d7SDimitry Andric   OS.emitInt16(uint16_t(EndKind)); // Record Kind
3204d8e91e46SDimitry Andric }
3205d8e91e46SDimitry Andric 
emitDebugInfoForUDTs(const std::vector<std::pair<std::string,const DIType * >> & UDTs)320601095a5dSDimitry Andric void CodeViewDebug::emitDebugInfoForUDTs(
3207cfca06d7SDimitry Andric     const std::vector<std::pair<std::string, const DIType *>> &UDTs) {
3208cfca06d7SDimitry Andric #ifndef NDEBUG
3209cfca06d7SDimitry Andric   size_t OriginalSize = UDTs.size();
3210cfca06d7SDimitry Andric #endif
3211044eb2f6SDimitry Andric   for (const auto &UDT : UDTs) {
3212044eb2f6SDimitry Andric     const DIType *T = UDT.second;
3213044eb2f6SDimitry Andric     assert(shouldEmitUdt(T));
3214d8e91e46SDimitry Andric     MCSymbol *UDTRecordEnd = beginSymbolRecord(SymbolKind::S_UDT);
321501095a5dSDimitry Andric     OS.AddComment("Type");
3216cfca06d7SDimitry Andric     OS.emitInt32(getCompleteTypeIndex(T).getIndex());
3217cfca06d7SDimitry Andric     assert(OriginalSize == UDTs.size() &&
3218cfca06d7SDimitry Andric            "getCompleteTypeIndex found new UDTs!");
321901095a5dSDimitry Andric     emitNullTerminatedSymbolName(OS, UDT.first);
3220d8e91e46SDimitry Andric     endSymbolRecord(UDTRecordEnd);
322101095a5dSDimitry Andric   }
322201095a5dSDimitry Andric }
322301095a5dSDimitry Andric 
collectGlobalVariableInfo()3224d8e91e46SDimitry Andric void CodeViewDebug::collectGlobalVariableInfo() {
3225b915e9e0SDimitry Andric   DenseMap<const DIGlobalVariableExpression *, const GlobalVariable *>
3226b915e9e0SDimitry Andric       GlobalMap;
3227b915e9e0SDimitry Andric   for (const GlobalVariable &GV : MMI->getModule()->globals()) {
3228b915e9e0SDimitry Andric     SmallVector<DIGlobalVariableExpression *, 1> GVEs;
3229b915e9e0SDimitry Andric     GV.getDebugInfo(GVEs);
3230b915e9e0SDimitry Andric     for (const auto *GVE : GVEs)
3231b915e9e0SDimitry Andric       GlobalMap[GVE] = &GV;
3232b915e9e0SDimitry Andric   }
3233b915e9e0SDimitry Andric 
323401095a5dSDimitry Andric   NamedMDNode *CUs = MMI->getModule()->getNamedMetadata("llvm.dbg.cu");
323501095a5dSDimitry Andric   for (const MDNode *Node : CUs->operands()) {
323601095a5dSDimitry Andric     const auto *CU = cast<DICompileUnit>(Node);
3237d8e91e46SDimitry Andric     for (const auto *GVE : CU->getGlobalVariables()) {
3238e6d15924SDimitry Andric       const DIGlobalVariable *DIGV = GVE->getVariable();
3239e6d15924SDimitry Andric       const DIExpression *DIE = GVE->getExpression();
3240145449b1SDimitry Andric       // Don't emit string literals in CodeView, as the only useful parts are
3241145449b1SDimitry Andric       // generally the filename and line number, which isn't possible to output
3242145449b1SDimitry Andric       // in CodeView. String literals should be the only unnamed GlobalVariable
3243145449b1SDimitry Andric       // with debug info.
3244145449b1SDimitry Andric       if (DIGV->getName().empty()) continue;
3245e6d15924SDimitry Andric 
3246c0981da4SDimitry Andric       if ((DIE->getNumElements() == 2) &&
3247c0981da4SDimitry Andric           (DIE->getElement(0) == dwarf::DW_OP_plus_uconst))
3248c0981da4SDimitry Andric         // Record the constant offset for the variable.
3249c0981da4SDimitry Andric         //
3250c0981da4SDimitry Andric         // A Fortran common block uses this idiom to encode the offset
3251c0981da4SDimitry Andric         // of a variable from the common block's starting address.
3252c0981da4SDimitry Andric         CVGlobalVariableOffsets.insert(
3253c0981da4SDimitry Andric             std::make_pair(DIGV, DIE->getElement(1)));
3254c0981da4SDimitry Andric 
3255e6d15924SDimitry Andric       // Emit constant global variables in a global symbol section.
3256e6d15924SDimitry Andric       if (GlobalMap.count(GVE) == 0 && DIE->isConstant()) {
3257e6d15924SDimitry Andric         CVGlobalVariable CVGV = {DIGV, DIE};
3258e6d15924SDimitry Andric         GlobalVariables.emplace_back(std::move(CVGV));
3259e6d15924SDimitry Andric       }
3260e6d15924SDimitry Andric 
3261d8e91e46SDimitry Andric       const auto *GV = GlobalMap.lookup(GVE);
3262d8e91e46SDimitry Andric       if (!GV || GV->isDeclarationForLinker())
3263d8e91e46SDimitry Andric         continue;
3264e6d15924SDimitry Andric 
3265d8e91e46SDimitry Andric       DIScope *Scope = DIGV->getScope();
3266d8e91e46SDimitry Andric       SmallVector<CVGlobalVariable, 1> *VariableList;
3267d8e91e46SDimitry Andric       if (Scope && isa<DILocalScope>(Scope)) {
3268d8e91e46SDimitry Andric         // Locate a global variable list for this scope, creating one if
3269d8e91e46SDimitry Andric         // necessary.
3270d8e91e46SDimitry Andric         auto Insertion = ScopeGlobals.insert(
3271d8e91e46SDimitry Andric             {Scope, std::unique_ptr<GlobalVariableList>()});
3272d8e91e46SDimitry Andric         if (Insertion.second)
32731d5ae102SDimitry Andric           Insertion.first->second = std::make_unique<GlobalVariableList>();
3274d8e91e46SDimitry Andric         VariableList = Insertion.first->second.get();
3275d8e91e46SDimitry Andric       } else if (GV->hasComdat())
3276d8e91e46SDimitry Andric         // Emit this global variable into a COMDAT section.
3277d8e91e46SDimitry Andric         VariableList = &ComdatVariables;
3278d8e91e46SDimitry Andric       else
3279e6d15924SDimitry Andric         // Emit this global variable in a single global symbol section.
3280d8e91e46SDimitry Andric         VariableList = &GlobalVariables;
3281d8e91e46SDimitry Andric       CVGlobalVariable CVGV = {DIGV, GV};
3282d8e91e46SDimitry Andric       VariableList->emplace_back(std::move(CVGV));
3283d8e91e46SDimitry Andric     }
3284d8e91e46SDimitry Andric   }
3285d8e91e46SDimitry Andric }
328601095a5dSDimitry Andric 
collectDebugInfoForGlobals()3287b60736ecSDimitry Andric void CodeViewDebug::collectDebugInfoForGlobals() {
3288b60736ecSDimitry Andric   for (const CVGlobalVariable &CVGV : GlobalVariables) {
3289b60736ecSDimitry Andric     const DIGlobalVariable *DIGV = CVGV.DIGV;
3290b60736ecSDimitry Andric     const DIScope *Scope = DIGV->getScope();
3291b60736ecSDimitry Andric     getCompleteTypeIndex(DIGV->getType());
3292b60736ecSDimitry Andric     getFullyQualifiedName(Scope, DIGV->getName());
3293b60736ecSDimitry Andric   }
3294b60736ecSDimitry Andric 
3295b60736ecSDimitry Andric   for (const CVGlobalVariable &CVGV : ComdatVariables) {
3296b60736ecSDimitry Andric     const DIGlobalVariable *DIGV = CVGV.DIGV;
3297b60736ecSDimitry Andric     const DIScope *Scope = DIGV->getScope();
3298b60736ecSDimitry Andric     getCompleteTypeIndex(DIGV->getType());
3299b60736ecSDimitry Andric     getFullyQualifiedName(Scope, DIGV->getName());
3300b60736ecSDimitry Andric   }
3301b60736ecSDimitry Andric }
3302b60736ecSDimitry Andric 
emitDebugInfoForGlobals()3303d8e91e46SDimitry Andric void CodeViewDebug::emitDebugInfoForGlobals() {
330401095a5dSDimitry Andric   // First, emit all globals that are not in a comdat in a single symbol
330501095a5dSDimitry Andric   // substream. MSVC doesn't like it if the substream is empty, so only open
330601095a5dSDimitry Andric   // it if we have at least one global to emit.
330701095a5dSDimitry Andric   switchToDebugSectionForSymbol(nullptr);
3308b60736ecSDimitry Andric   if (!GlobalVariables.empty() || !StaticConstMembers.empty()) {
330901095a5dSDimitry Andric     OS.AddComment("Symbol subsection for globals");
3310d8e91e46SDimitry Andric     MCSymbol *EndLabel = beginCVSubsection(DebugSubsectionKind::Symbols);
3311d8e91e46SDimitry Andric     emitGlobalVariableList(GlobalVariables);
3312b60736ecSDimitry Andric     emitStaticConstMemberList();
331301095a5dSDimitry Andric     endCVSubsection(EndLabel);
3314d8e91e46SDimitry Andric   }
331501095a5dSDimitry Andric 
331601095a5dSDimitry Andric   // Second, emit each global that is in a comdat into its own .debug$S
331701095a5dSDimitry Andric   // section along with its own symbol substream.
3318d8e91e46SDimitry Andric   for (const CVGlobalVariable &CVGV : ComdatVariables) {
33197fa27ce4SDimitry Andric     const GlobalVariable *GV = cast<const GlobalVariable *>(CVGV.GVInfo);
3320e6d15924SDimitry Andric     MCSymbol *GVSym = Asm->getSymbol(GV);
332101095a5dSDimitry Andric     OS.AddComment("Symbol subsection for " +
3322e6d15924SDimitry Andric                   Twine(GlobalValue::dropLLVMManglingEscape(GV->getName())));
332301095a5dSDimitry Andric     switchToDebugSectionForSymbol(GVSym);
3324d8e91e46SDimitry Andric     MCSymbol *EndLabel = beginCVSubsection(DebugSubsectionKind::Symbols);
3325b915e9e0SDimitry Andric     // FIXME: emitDebugInfoForGlobal() doesn't handle DIExpressions.
3326e6d15924SDimitry Andric     emitDebugInfoForGlobal(CVGV);
332701095a5dSDimitry Andric     endCVSubsection(EndLabel);
332801095a5dSDimitry Andric   }
332901095a5dSDimitry Andric }
333001095a5dSDimitry Andric 
emitDebugInfoForRetainedTypes()333101095a5dSDimitry Andric void CodeViewDebug::emitDebugInfoForRetainedTypes() {
333201095a5dSDimitry Andric   NamedMDNode *CUs = MMI->getModule()->getNamedMetadata("llvm.dbg.cu");
333301095a5dSDimitry Andric   for (const MDNode *Node : CUs->operands()) {
333401095a5dSDimitry Andric     for (auto *Ty : cast<DICompileUnit>(Node)->getRetainedTypes()) {
333501095a5dSDimitry Andric       if (DIType *RT = dyn_cast<DIType>(Ty)) {
333601095a5dSDimitry Andric         getTypeIndex(RT);
333701095a5dSDimitry Andric         // FIXME: Add to global/local DTU list.
333801095a5dSDimitry Andric       }
333901095a5dSDimitry Andric     }
334001095a5dSDimitry Andric   }
334101095a5dSDimitry Andric }
334201095a5dSDimitry Andric 
3343d8e91e46SDimitry Andric // Emit each global variable in the specified array.
emitGlobalVariableList(ArrayRef<CVGlobalVariable> Globals)3344d8e91e46SDimitry Andric void CodeViewDebug::emitGlobalVariableList(ArrayRef<CVGlobalVariable> Globals) {
3345d8e91e46SDimitry Andric   for (const CVGlobalVariable &CVGV : Globals) {
3346d8e91e46SDimitry Andric     // FIXME: emitDebugInfoForGlobal() doesn't handle DIExpressions.
3347e6d15924SDimitry Andric     emitDebugInfoForGlobal(CVGV);
3348d8e91e46SDimitry Andric   }
3349d8e91e46SDimitry Andric }
3350d8e91e46SDimitry Andric 
emitConstantSymbolRecord(const DIType * DTy,APSInt & Value,const std::string & QualifiedName)3351344a3780SDimitry Andric void CodeViewDebug::emitConstantSymbolRecord(const DIType *DTy, APSInt &Value,
3352344a3780SDimitry Andric                                              const std::string &QualifiedName) {
3353344a3780SDimitry Andric   MCSymbol *SConstantEnd = beginSymbolRecord(SymbolKind::S_CONSTANT);
3354344a3780SDimitry Andric   OS.AddComment("Type");
3355344a3780SDimitry Andric   OS.emitInt32(getTypeIndex(DTy).getIndex());
3356344a3780SDimitry Andric 
3357344a3780SDimitry Andric   OS.AddComment("Value");
3358344a3780SDimitry Andric 
3359344a3780SDimitry Andric   // Encoded integers shouldn't need more than 10 bytes.
3360344a3780SDimitry Andric   uint8_t Data[10];
3361b1c73532SDimitry Andric   BinaryStreamWriter Writer(Data, llvm::endianness::little);
3362344a3780SDimitry Andric   CodeViewRecordIO IO(Writer);
3363344a3780SDimitry Andric   cantFail(IO.mapEncodedInteger(Value));
3364344a3780SDimitry Andric   StringRef SRef((char *)Data, Writer.getOffset());
3365344a3780SDimitry Andric   OS.emitBinaryData(SRef);
3366344a3780SDimitry Andric 
3367344a3780SDimitry Andric   OS.AddComment("Name");
3368344a3780SDimitry Andric   emitNullTerminatedSymbolName(OS, QualifiedName);
3369344a3780SDimitry Andric   endSymbolRecord(SConstantEnd);
3370344a3780SDimitry Andric }
3371344a3780SDimitry Andric 
emitStaticConstMemberList()3372b60736ecSDimitry Andric void CodeViewDebug::emitStaticConstMemberList() {
3373b60736ecSDimitry Andric   for (const DIDerivedType *DTy : StaticConstMembers) {
3374b60736ecSDimitry Andric     const DIScope *Scope = DTy->getScope();
3375b60736ecSDimitry Andric 
3376b60736ecSDimitry Andric     APSInt Value;
3377b60736ecSDimitry Andric     if (const ConstantInt *CI =
3378b60736ecSDimitry Andric             dyn_cast_or_null<ConstantInt>(DTy->getConstant()))
3379b60736ecSDimitry Andric       Value = APSInt(CI->getValue(),
3380b60736ecSDimitry Andric                      DebugHandlerBase::isUnsignedDIType(DTy->getBaseType()));
3381b60736ecSDimitry Andric     else if (const ConstantFP *CFP =
3382b60736ecSDimitry Andric                  dyn_cast_or_null<ConstantFP>(DTy->getConstant()))
3383b60736ecSDimitry Andric       Value = APSInt(CFP->getValueAPF().bitcastToAPInt(), true);
3384b60736ecSDimitry Andric     else
3385b60736ecSDimitry Andric       llvm_unreachable("cannot emit a constant without a value");
3386b60736ecSDimitry Andric 
3387344a3780SDimitry Andric     emitConstantSymbolRecord(DTy->getBaseType(), Value,
3388344a3780SDimitry Andric                              getFullyQualifiedName(Scope, DTy->getName()));
3389b60736ecSDimitry Andric   }
3390b60736ecSDimitry Andric }
3391b60736ecSDimitry Andric 
isFloatDIType(const DIType * Ty)3392b60736ecSDimitry Andric static bool isFloatDIType(const DIType *Ty) {
3393b60736ecSDimitry Andric   if (isa<DICompositeType>(Ty))
3394b60736ecSDimitry Andric     return false;
3395b60736ecSDimitry Andric 
3396b60736ecSDimitry Andric   if (auto *DTy = dyn_cast<DIDerivedType>(Ty)) {
3397b60736ecSDimitry Andric     dwarf::Tag T = (dwarf::Tag)Ty->getTag();
3398b60736ecSDimitry Andric     if (T == dwarf::DW_TAG_pointer_type ||
3399b60736ecSDimitry Andric         T == dwarf::DW_TAG_ptr_to_member_type ||
3400b60736ecSDimitry Andric         T == dwarf::DW_TAG_reference_type ||
3401b60736ecSDimitry Andric         T == dwarf::DW_TAG_rvalue_reference_type)
3402b60736ecSDimitry Andric       return false;
3403b60736ecSDimitry Andric     assert(DTy->getBaseType() && "Expected valid base type");
3404b60736ecSDimitry Andric     return isFloatDIType(DTy->getBaseType());
3405b60736ecSDimitry Andric   }
3406b60736ecSDimitry Andric 
3407b60736ecSDimitry Andric   auto *BTy = cast<DIBasicType>(Ty);
3408b60736ecSDimitry Andric   return (BTy->getEncoding() == dwarf::DW_ATE_float);
3409b60736ecSDimitry Andric }
3410b60736ecSDimitry Andric 
emitDebugInfoForGlobal(const CVGlobalVariable & CVGV)3411e6d15924SDimitry Andric void CodeViewDebug::emitDebugInfoForGlobal(const CVGlobalVariable &CVGV) {
3412e6d15924SDimitry Andric   const DIGlobalVariable *DIGV = CVGV.DIGV;
3413cfca06d7SDimitry Andric 
3414cfca06d7SDimitry Andric   const DIScope *Scope = DIGV->getScope();
3415cfca06d7SDimitry Andric   // For static data members, get the scope from the declaration.
3416cfca06d7SDimitry Andric   if (const auto *MemberDecl = dyn_cast_or_null<DIDerivedType>(
3417cfca06d7SDimitry Andric           DIGV->getRawStaticDataMemberDeclaration()))
3418cfca06d7SDimitry Andric     Scope = MemberDecl->getScope();
3419e3b55780SDimitry Andric   // For static local variables and Fortran, the scoping portion is elided
3420e3b55780SDimitry Andric   // in its name so that we can reference the variable in the command line
3421e3b55780SDimitry Andric   // of the VS debugger.
3422c0981da4SDimitry Andric   std::string QualifiedName =
3423e3b55780SDimitry Andric       (moduleIsInFortran() || (Scope && isa<DILocalScope>(Scope)))
3424e3b55780SDimitry Andric           ? std::string(DIGV->getName())
3425c0981da4SDimitry Andric           : getFullyQualifiedName(Scope, DIGV->getName());
3426cfca06d7SDimitry Andric 
3427e6d15924SDimitry Andric   if (const GlobalVariable *GV =
34287fa27ce4SDimitry Andric           dyn_cast_if_present<const GlobalVariable *>(CVGV.GVInfo)) {
3429d8e91e46SDimitry Andric     // DataSym record, see SymbolRecord.h for more info. Thread local data
3430d8e91e46SDimitry Andric     // happens to have the same format as global data.
3431e6d15924SDimitry Andric     MCSymbol *GVSym = Asm->getSymbol(GV);
3432d8e91e46SDimitry Andric     SymbolKind DataSym = GV->isThreadLocal()
3433d8e91e46SDimitry Andric                              ? (DIGV->isLocalToUnit() ? SymbolKind::S_LTHREAD32
3434d8e91e46SDimitry Andric                                                       : SymbolKind::S_GTHREAD32)
3435d8e91e46SDimitry Andric                              : (DIGV->isLocalToUnit() ? SymbolKind::S_LDATA32
3436d8e91e46SDimitry Andric                                                       : SymbolKind::S_GDATA32);
3437d8e91e46SDimitry Andric     MCSymbol *DataEnd = beginSymbolRecord(DataSym);
343801095a5dSDimitry Andric     OS.AddComment("Type");
3439cfca06d7SDimitry Andric     OS.emitInt32(getCompleteTypeIndex(DIGV->getType()).getIndex());
344001095a5dSDimitry Andric     OS.AddComment("DataOffset");
3441c0981da4SDimitry Andric 
3442c0981da4SDimitry Andric     uint64_t Offset = 0;
34437fa27ce4SDimitry Andric     if (CVGlobalVariableOffsets.contains(DIGV))
3444c0981da4SDimitry Andric       // Use the offset seen while collecting info on globals.
3445c0981da4SDimitry Andric       Offset = CVGlobalVariableOffsets[DIGV];
3446145449b1SDimitry Andric     OS.emitCOFFSecRel32(GVSym, Offset);
3447c0981da4SDimitry Andric 
344801095a5dSDimitry Andric     OS.AddComment("Segment");
3449145449b1SDimitry Andric     OS.emitCOFFSectionIndex(GVSym);
345001095a5dSDimitry Andric     OS.AddComment("Name");
3451d8e91e46SDimitry Andric     const unsigned LengthOfDataRecord = 12;
3452cfca06d7SDimitry Andric     emitNullTerminatedSymbolName(OS, QualifiedName, LengthOfDataRecord);
3453d8e91e46SDimitry Andric     endSymbolRecord(DataEnd);
3454e6d15924SDimitry Andric   } else {
34557fa27ce4SDimitry Andric     const DIExpression *DIE = cast<const DIExpression *>(CVGV.GVInfo);
3456e6d15924SDimitry Andric     assert(DIE->isConstant() &&
3457e6d15924SDimitry Andric            "Global constant variables must contain a constant expression.");
3458b60736ecSDimitry Andric 
3459b60736ecSDimitry Andric     // Use unsigned for floats.
3460b60736ecSDimitry Andric     bool isUnsigned = isFloatDIType(DIGV->getType())
3461b60736ecSDimitry Andric                           ? true
3462b60736ecSDimitry Andric                           : DebugHandlerBase::isUnsignedDIType(DIGV->getType());
3463b60736ecSDimitry Andric     APSInt Value(APInt(/*BitWidth=*/64, DIE->getElement(1)), isUnsigned);
3464344a3780SDimitry Andric     emitConstantSymbolRecord(DIGV->getType(), Value, QualifiedName);
3465e6d15924SDimitry Andric   }
346601095a5dSDimitry Andric }
3467b1c73532SDimitry Andric 
forEachJumpTableBranch(const MachineFunction * MF,bool isThumb,const std::function<void (const MachineJumpTableInfo &,const MachineInstr &,int64_t)> & Callback)3468b1c73532SDimitry Andric void forEachJumpTableBranch(
3469b1c73532SDimitry Andric     const MachineFunction *MF, bool isThumb,
3470b1c73532SDimitry Andric     const std::function<void(const MachineJumpTableInfo &, const MachineInstr &,
3471b1c73532SDimitry Andric                              int64_t)> &Callback) {
3472b1c73532SDimitry Andric   auto JTI = MF->getJumpTableInfo();
3473b1c73532SDimitry Andric   if (JTI && !JTI->isEmpty()) {
3474b1c73532SDimitry Andric #ifndef NDEBUG
3475b1c73532SDimitry Andric     auto UsedJTs = llvm::SmallBitVector(JTI->getJumpTables().size());
3476b1c73532SDimitry Andric #endif
3477b1c73532SDimitry Andric     for (const auto &MBB : *MF) {
3478b1c73532SDimitry Andric       // Search for indirect branches...
3479b1c73532SDimitry Andric       const auto LastMI = MBB.getFirstTerminator();
3480b1c73532SDimitry Andric       if (LastMI != MBB.end() && LastMI->isIndirectBranch()) {
3481b1c73532SDimitry Andric         if (isThumb) {
3482b1c73532SDimitry Andric           // ... that directly use jump table operands.
3483b1c73532SDimitry Andric           // NOTE: ARM uses pattern matching to lower its BR_JT SDNode to
3484b1c73532SDimitry Andric           // machine instructions, hence inserting a JUMP_TABLE_DEBUG_INFO node
3485b1c73532SDimitry Andric           // interferes with this process *but* the resulting pseudo-instruction
3486b1c73532SDimitry Andric           // uses a Jump Table operand, so extract the jump table index directly
3487b1c73532SDimitry Andric           // from that.
3488b1c73532SDimitry Andric           for (const auto &MO : LastMI->operands()) {
3489b1c73532SDimitry Andric             if (MO.isJTI()) {
3490b1c73532SDimitry Andric               unsigned Index = MO.getIndex();
3491b1c73532SDimitry Andric #ifndef NDEBUG
3492b1c73532SDimitry Andric               UsedJTs.set(Index);
3493b1c73532SDimitry Andric #endif
3494b1c73532SDimitry Andric               Callback(*JTI, *LastMI, Index);
3495b1c73532SDimitry Andric               break;
3496b1c73532SDimitry Andric             }
3497b1c73532SDimitry Andric           }
3498b1c73532SDimitry Andric         } else {
3499b1c73532SDimitry Andric           // ... that have jump table debug info.
3500b1c73532SDimitry Andric           // NOTE: The debug info is inserted as a JUMP_TABLE_DEBUG_INFO node
3501b1c73532SDimitry Andric           // when lowering the BR_JT SDNode to an indirect branch.
3502b1c73532SDimitry Andric           for (auto I = MBB.instr_rbegin(), E = MBB.instr_rend(); I != E; ++I) {
3503b1c73532SDimitry Andric             if (I->isJumpTableDebugInfo()) {
3504b1c73532SDimitry Andric               unsigned Index = I->getOperand(0).getImm();
3505b1c73532SDimitry Andric #ifndef NDEBUG
3506b1c73532SDimitry Andric               UsedJTs.set(Index);
3507b1c73532SDimitry Andric #endif
3508b1c73532SDimitry Andric               Callback(*JTI, *LastMI, Index);
3509b1c73532SDimitry Andric               break;
3510b1c73532SDimitry Andric             }
3511b1c73532SDimitry Andric           }
3512b1c73532SDimitry Andric         }
3513b1c73532SDimitry Andric       }
3514b1c73532SDimitry Andric     }
3515b1c73532SDimitry Andric #ifndef NDEBUG
3516b1c73532SDimitry Andric     assert(UsedJTs.all() &&
3517b1c73532SDimitry Andric            "Some of jump tables were not used in a debug info instruction");
3518b1c73532SDimitry Andric #endif
3519b1c73532SDimitry Andric   }
3520b1c73532SDimitry Andric }
3521b1c73532SDimitry Andric 
discoverJumpTableBranches(const MachineFunction * MF,bool isThumb)3522b1c73532SDimitry Andric void CodeViewDebug::discoverJumpTableBranches(const MachineFunction *MF,
3523b1c73532SDimitry Andric                                               bool isThumb) {
3524b1c73532SDimitry Andric   forEachJumpTableBranch(
3525b1c73532SDimitry Andric       MF, isThumb,
3526b1c73532SDimitry Andric       [this](const MachineJumpTableInfo &, const MachineInstr &BranchMI,
3527b1c73532SDimitry Andric              int64_t) { requestLabelBeforeInsn(&BranchMI); });
3528b1c73532SDimitry Andric }
3529b1c73532SDimitry Andric 
collectDebugInfoForJumpTables(const MachineFunction * MF,bool isThumb)3530b1c73532SDimitry Andric void CodeViewDebug::collectDebugInfoForJumpTables(const MachineFunction *MF,
3531b1c73532SDimitry Andric                                                   bool isThumb) {
3532b1c73532SDimitry Andric   forEachJumpTableBranch(
3533b1c73532SDimitry Andric       MF, isThumb,
3534b1c73532SDimitry Andric       [this, MF](const MachineJumpTableInfo &JTI, const MachineInstr &BranchMI,
3535b1c73532SDimitry Andric                  int64_t JumpTableIndex) {
3536b1c73532SDimitry Andric         // For label-difference jump tables, find the base expression.
3537b1c73532SDimitry Andric         // Otherwise the jump table uses an absolute address (so no base
3538b1c73532SDimitry Andric         // is required).
3539b1c73532SDimitry Andric         const MCSymbol *Base;
3540b1c73532SDimitry Andric         uint64_t BaseOffset = 0;
3541b1c73532SDimitry Andric         const MCSymbol *Branch = getLabelBeforeInsn(&BranchMI);
3542b1c73532SDimitry Andric         JumpTableEntrySize EntrySize;
3543b1c73532SDimitry Andric         switch (JTI.getEntryKind()) {
3544b1c73532SDimitry Andric         case MachineJumpTableInfo::EK_Custom32:
3545b1c73532SDimitry Andric         case MachineJumpTableInfo::EK_GPRel32BlockAddress:
3546b1c73532SDimitry Andric         case MachineJumpTableInfo::EK_GPRel64BlockAddress:
3547b1c73532SDimitry Andric           llvm_unreachable(
3548b1c73532SDimitry Andric               "EK_Custom32, EK_GPRel32BlockAddress, and "
3549b1c73532SDimitry Andric               "EK_GPRel64BlockAddress should never be emitted for COFF");
3550b1c73532SDimitry Andric         case MachineJumpTableInfo::EK_BlockAddress:
3551b1c73532SDimitry Andric           // Each entry is an absolute address.
3552b1c73532SDimitry Andric           EntrySize = JumpTableEntrySize::Pointer;
3553b1c73532SDimitry Andric           Base = nullptr;
3554b1c73532SDimitry Andric           break;
3555b1c73532SDimitry Andric         case MachineJumpTableInfo::EK_Inline:
3556b1c73532SDimitry Andric         case MachineJumpTableInfo::EK_LabelDifference32:
3557b1c73532SDimitry Andric         case MachineJumpTableInfo::EK_LabelDifference64:
3558b1c73532SDimitry Andric           // Ask the AsmPrinter.
3559b1c73532SDimitry Andric           std::tie(Base, BaseOffset, Branch, EntrySize) =
3560b1c73532SDimitry Andric               Asm->getCodeViewJumpTableInfo(JumpTableIndex, &BranchMI, Branch);
3561b1c73532SDimitry Andric           break;
3562b1c73532SDimitry Andric         }
3563b1c73532SDimitry Andric 
3564b1c73532SDimitry Andric         CurFn->JumpTables.push_back(
3565b1c73532SDimitry Andric             {EntrySize, Base, BaseOffset, Branch,
3566b1c73532SDimitry Andric              MF->getJTISymbol(JumpTableIndex, MMI->getContext()),
3567b1c73532SDimitry Andric              JTI.getJumpTables()[JumpTableIndex].MBBs.size()});
3568b1c73532SDimitry Andric       });
3569b1c73532SDimitry Andric }
3570b1c73532SDimitry Andric 
emitDebugInfoForJumpTables(const FunctionInfo & FI)3571b1c73532SDimitry Andric void CodeViewDebug::emitDebugInfoForJumpTables(const FunctionInfo &FI) {
3572b1c73532SDimitry Andric   for (auto JumpTable : FI.JumpTables) {
3573b1c73532SDimitry Andric     MCSymbol *JumpTableEnd = beginSymbolRecord(SymbolKind::S_ARMSWITCHTABLE);
3574b1c73532SDimitry Andric     if (JumpTable.Base) {
3575b1c73532SDimitry Andric       OS.AddComment("Base offset");
3576b1c73532SDimitry Andric       OS.emitCOFFSecRel32(JumpTable.Base, JumpTable.BaseOffset);
3577b1c73532SDimitry Andric       OS.AddComment("Base section index");
3578b1c73532SDimitry Andric       OS.emitCOFFSectionIndex(JumpTable.Base);
3579b1c73532SDimitry Andric     } else {
3580b1c73532SDimitry Andric       OS.AddComment("Base offset");
3581b1c73532SDimitry Andric       OS.emitInt32(0);
3582b1c73532SDimitry Andric       OS.AddComment("Base section index");
3583b1c73532SDimitry Andric       OS.emitInt16(0);
3584b1c73532SDimitry Andric     }
3585b1c73532SDimitry Andric     OS.AddComment("Switch type");
3586b1c73532SDimitry Andric     OS.emitInt16(static_cast<uint16_t>(JumpTable.EntrySize));
3587b1c73532SDimitry Andric     OS.AddComment("Branch offset");
3588b1c73532SDimitry Andric     OS.emitCOFFSecRel32(JumpTable.Branch, /*Offset=*/0);
3589b1c73532SDimitry Andric     OS.AddComment("Table offset");
3590b1c73532SDimitry Andric     OS.emitCOFFSecRel32(JumpTable.Table, /*Offset=*/0);
3591b1c73532SDimitry Andric     OS.AddComment("Branch section index");
3592b1c73532SDimitry Andric     OS.emitCOFFSectionIndex(JumpTable.Branch);
3593b1c73532SDimitry Andric     OS.AddComment("Table section index");
3594b1c73532SDimitry Andric     OS.emitCOFFSectionIndex(JumpTable.Table);
3595b1c73532SDimitry Andric     OS.AddComment("Entries count");
3596b1c73532SDimitry Andric     OS.emitInt32(JumpTable.TableSize);
3597b1c73532SDimitry Andric     endSymbolRecord(JumpTableEnd);
3598b1c73532SDimitry Andric   }
3599b1c73532SDimitry Andric }
3600b1c73532SDimitry Andric 
emitInlinees(const SmallSet<codeview::TypeIndex,1> & Inlinees)3601b1c73532SDimitry Andric void CodeViewDebug::emitInlinees(
3602b1c73532SDimitry Andric     const SmallSet<codeview::TypeIndex, 1> &Inlinees) {
3603b1c73532SDimitry Andric   // Divide the list of inlinees into chunks such that each chunk fits within
3604b1c73532SDimitry Andric   // one record.
3605b1c73532SDimitry Andric   constexpr size_t ChunkSize =
3606b1c73532SDimitry Andric       (MaxRecordLength - sizeof(SymbolKind) - sizeof(uint32_t)) /
3607b1c73532SDimitry Andric       sizeof(uint32_t);
3608b1c73532SDimitry Andric 
3609b1c73532SDimitry Andric   SmallVector<TypeIndex> SortedInlinees{Inlinees.begin(), Inlinees.end()};
3610b1c73532SDimitry Andric   llvm::sort(SortedInlinees);
3611b1c73532SDimitry Andric 
3612b1c73532SDimitry Andric   size_t CurrentIndex = 0;
3613b1c73532SDimitry Andric   while (CurrentIndex < SortedInlinees.size()) {
3614b1c73532SDimitry Andric     auto Symbol = beginSymbolRecord(SymbolKind::S_INLINEES);
3615b1c73532SDimitry Andric     auto CurrentChunkSize =
3616b1c73532SDimitry Andric         std::min(ChunkSize, SortedInlinees.size() - CurrentIndex);
3617b1c73532SDimitry Andric     OS.AddComment("Count");
3618b1c73532SDimitry Andric     OS.emitInt32(CurrentChunkSize);
3619b1c73532SDimitry Andric 
3620b1c73532SDimitry Andric     const size_t CurrentChunkEnd = CurrentIndex + CurrentChunkSize;
3621b1c73532SDimitry Andric     for (; CurrentIndex < CurrentChunkEnd; ++CurrentIndex) {
3622b1c73532SDimitry Andric       OS.AddComment("Inlinee");
3623b1c73532SDimitry Andric       OS.emitInt32(SortedInlinees[CurrentIndex].getIndex());
3624b1c73532SDimitry Andric     }
3625b1c73532SDimitry Andric     endSymbolRecord(Symbol);
3626b1c73532SDimitry Andric   }
3627b1c73532SDimitry Andric }
3628