106c3fb27SDimitry Andric //===-- LVCodeViewVisitor.cpp ---------------------------------------------===//
206c3fb27SDimitry Andric //
306c3fb27SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
406c3fb27SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
506c3fb27SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
606c3fb27SDimitry Andric //
706c3fb27SDimitry Andric //===----------------------------------------------------------------------===//
806c3fb27SDimitry Andric //
906c3fb27SDimitry Andric // This implements the LVCodeViewVisitor class.
1006c3fb27SDimitry Andric //
1106c3fb27SDimitry Andric //===----------------------------------------------------------------------===//
1206c3fb27SDimitry Andric 
1306c3fb27SDimitry Andric #include "llvm/DebugInfo/LogicalView/Readers/LVCodeViewVisitor.h"
1406c3fb27SDimitry Andric #include "llvm/BinaryFormat/Magic.h"
1506c3fb27SDimitry Andric #include "llvm/DebugInfo/CodeView/EnumTables.h"
1606c3fb27SDimitry Andric #include "llvm/DebugInfo/CodeView/LazyRandomTypeCollection.h"
1706c3fb27SDimitry Andric #include "llvm/DebugInfo/CodeView/SymbolRecordHelpers.h"
1806c3fb27SDimitry Andric #include "llvm/DebugInfo/CodeView/TypeRecordHelpers.h"
1906c3fb27SDimitry Andric #include "llvm/DebugInfo/CodeView/TypeVisitorCallbackPipeline.h"
2006c3fb27SDimitry Andric #include "llvm/DebugInfo/LogicalView/Core/LVScope.h"
2106c3fb27SDimitry Andric #include "llvm/DebugInfo/LogicalView/Core/LVSymbol.h"
2206c3fb27SDimitry Andric #include "llvm/DebugInfo/LogicalView/Core/LVType.h"
2306c3fb27SDimitry Andric #include "llvm/DebugInfo/LogicalView/Readers/LVCodeViewReader.h"
2406c3fb27SDimitry Andric #include "llvm/DebugInfo/PDB/Native/DbiStream.h"
2506c3fb27SDimitry Andric #include "llvm/DebugInfo/PDB/Native/InputFile.h"
2606c3fb27SDimitry Andric #include "llvm/DebugInfo/PDB/Native/NativeSession.h"
2706c3fb27SDimitry Andric #include "llvm/DebugInfo/PDB/Native/PDBFile.h"
2806c3fb27SDimitry Andric #include "llvm/DebugInfo/PDB/Native/PDBStringTable.h"
2906c3fb27SDimitry Andric #include "llvm/DebugInfo/PDB/Native/RawError.h"
3006c3fb27SDimitry Andric #include "llvm/DebugInfo/PDB/Native/TpiStream.h"
3106c3fb27SDimitry Andric #include "llvm/DebugInfo/PDB/PDB.h"
3206c3fb27SDimitry Andric #include "llvm/Demangle/Demangle.h"
3306c3fb27SDimitry Andric #include "llvm/Object/COFF.h"
3406c3fb27SDimitry Andric #include "llvm/Support/Error.h"
3506c3fb27SDimitry Andric #include "llvm/Support/FileSystem.h"
3606c3fb27SDimitry Andric #include "llvm/Support/FormatAdapters.h"
3706c3fb27SDimitry Andric #include "llvm/Support/FormatVariadic.h"
3806c3fb27SDimitry Andric 
3906c3fb27SDimitry Andric using namespace llvm;
4006c3fb27SDimitry Andric using namespace llvm::codeview;
4106c3fb27SDimitry Andric using namespace llvm::object;
4206c3fb27SDimitry Andric using namespace llvm::pdb;
4306c3fb27SDimitry Andric using namespace llvm::logicalview;
4406c3fb27SDimitry Andric 
4506c3fb27SDimitry Andric #define DEBUG_TYPE "CodeViewUtilities"
4606c3fb27SDimitry Andric 
4706c3fb27SDimitry Andric namespace llvm {
4806c3fb27SDimitry Andric namespace logicalview {
4906c3fb27SDimitry Andric 
getTrueType(TypeIndex & TI)5006c3fb27SDimitry Andric static TypeIndex getTrueType(TypeIndex &TI) {
5106c3fb27SDimitry Andric   // Dealing with a MSVC generated PDB, we encountered a type index with the
5206c3fb27SDimitry Andric   // value of: 0x0280xxxx where xxxx=0000.
5306c3fb27SDimitry Andric   //
5406c3fb27SDimitry Andric   // There is some documentation about type indices:
5506c3fb27SDimitry Andric   // https://llvm.org/docs/PDB/TpiStream.html
5606c3fb27SDimitry Andric   //
5706c3fb27SDimitry Andric   // A type index is a 32-bit integer that uniquely identifies a type inside
5806c3fb27SDimitry Andric   // of an object file’s .debug$T section or a PDB file’s TPI or IPI stream.
5906c3fb27SDimitry Andric   // The value of the type index for the first type record from the TPI stream
6006c3fb27SDimitry Andric   // is given by the TypeIndexBegin member of the TPI Stream Header although
6106c3fb27SDimitry Andric   // in practice this value is always equal to 0x1000 (4096).
6206c3fb27SDimitry Andric   //
6306c3fb27SDimitry Andric   // Any type index with a high bit set is considered to come from the IPI
6406c3fb27SDimitry Andric   // stream, although this appears to be more of a hack, and LLVM does not
6506c3fb27SDimitry Andric   // generate type indices of this nature. They can, however, be observed in
6606c3fb27SDimitry Andric   // Microsoft PDBs occasionally, so one should be prepared to handle them.
6706c3fb27SDimitry Andric   // Note that having the high bit set is not a necessary condition to
6806c3fb27SDimitry Andric   // determine whether a type index comes from the IPI stream, it is only
6906c3fb27SDimitry Andric   // sufficient.
7006c3fb27SDimitry Andric   LLVM_DEBUG(
7106c3fb27SDimitry Andric       { dbgs() << "Index before: " << HexNumber(TI.getIndex()) << "\n"; });
7206c3fb27SDimitry Andric   TI.setIndex(TI.getIndex() & 0x0000ffff);
7306c3fb27SDimitry Andric   LLVM_DEBUG(
7406c3fb27SDimitry Andric       { dbgs() << "Index after: " << HexNumber(TI.getIndex()) << "\n"; });
7506c3fb27SDimitry Andric   return TI;
7606c3fb27SDimitry Andric }
7706c3fb27SDimitry Andric 
7806c3fb27SDimitry Andric static const EnumEntry<TypeLeafKind> LeafTypeNames[] = {
7906c3fb27SDimitry Andric #define CV_TYPE(enum, val) {#enum, enum},
8006c3fb27SDimitry Andric #include "llvm/DebugInfo/CodeView/CodeViewTypes.def"
8106c3fb27SDimitry Andric };
8206c3fb27SDimitry Andric 
8306c3fb27SDimitry Andric // Return the type name pointed by the type index. It uses the kind to query
8406c3fb27SDimitry Andric // the associated name for the record type.
getRecordName(LazyRandomTypeCollection & Types,TypeIndex TI)8506c3fb27SDimitry Andric static StringRef getRecordName(LazyRandomTypeCollection &Types, TypeIndex TI) {
8606c3fb27SDimitry Andric   if (TI.isSimple())
8706c3fb27SDimitry Andric     return {};
8806c3fb27SDimitry Andric 
8906c3fb27SDimitry Andric   StringRef RecordName;
9006c3fb27SDimitry Andric   CVType CVReference = Types.getType(TI);
9106c3fb27SDimitry Andric   auto GetName = [&](auto Record) {
9206c3fb27SDimitry Andric     if (Error Err = TypeDeserializer::deserializeAs(
9306c3fb27SDimitry Andric             const_cast<CVType &>(CVReference), Record))
9406c3fb27SDimitry Andric       consumeError(std::move(Err));
9506c3fb27SDimitry Andric     else
9606c3fb27SDimitry Andric       RecordName = Record.getName();
9706c3fb27SDimitry Andric   };
9806c3fb27SDimitry Andric 
9906c3fb27SDimitry Andric   TypeRecordKind RK = static_cast<TypeRecordKind>(CVReference.kind());
10006c3fb27SDimitry Andric   if (RK == TypeRecordKind::Class || RK == TypeRecordKind::Struct)
10106c3fb27SDimitry Andric     GetName(ClassRecord(RK));
10206c3fb27SDimitry Andric   else if (RK == TypeRecordKind::Union)
10306c3fb27SDimitry Andric     GetName(UnionRecord(RK));
10406c3fb27SDimitry Andric   else if (RK == TypeRecordKind::Enum)
10506c3fb27SDimitry Andric     GetName(EnumRecord(RK));
10606c3fb27SDimitry Andric 
10706c3fb27SDimitry Andric   return RecordName;
10806c3fb27SDimitry Andric }
10906c3fb27SDimitry Andric 
11006c3fb27SDimitry Andric } // namespace logicalview
11106c3fb27SDimitry Andric } // namespace llvm
11206c3fb27SDimitry Andric 
11306c3fb27SDimitry Andric #undef DEBUG_TYPE
11406c3fb27SDimitry Andric #define DEBUG_TYPE "CodeViewDataVisitor"
11506c3fb27SDimitry Andric 
11606c3fb27SDimitry Andric namespace llvm {
11706c3fb27SDimitry Andric namespace logicalview {
11806c3fb27SDimitry Andric 
11906c3fb27SDimitry Andric // Keeps the type indexes with line information.
12006c3fb27SDimitry Andric using LVLineRecords = std::vector<TypeIndex>;
12106c3fb27SDimitry Andric 
12206c3fb27SDimitry Andric namespace {
12306c3fb27SDimitry Andric 
12406c3fb27SDimitry Andric class LVTypeRecords {
12506c3fb27SDimitry Andric   LVShared *Shared = nullptr;
12606c3fb27SDimitry Andric 
12706c3fb27SDimitry Andric   // Logical elements associated to their CodeView Type Index.
12806c3fb27SDimitry Andric   using RecordEntry = std::pair<TypeLeafKind, LVElement *>;
12906c3fb27SDimitry Andric   using RecordTable = std::map<TypeIndex, RecordEntry>;
13006c3fb27SDimitry Andric   RecordTable RecordFromTypes;
13106c3fb27SDimitry Andric   RecordTable RecordFromIds;
13206c3fb27SDimitry Andric 
13306c3fb27SDimitry Andric   using NameTable = std::map<StringRef, TypeIndex>;
13406c3fb27SDimitry Andric   NameTable NameFromTypes;
13506c3fb27SDimitry Andric   NameTable NameFromIds;
13606c3fb27SDimitry Andric 
13706c3fb27SDimitry Andric public:
LVTypeRecords(LVShared * Shared)13806c3fb27SDimitry Andric   LVTypeRecords(LVShared *Shared) : Shared(Shared) {}
13906c3fb27SDimitry Andric 
14006c3fb27SDimitry Andric   void add(uint32_t StreamIdx, TypeIndex TI, TypeLeafKind Kind,
14106c3fb27SDimitry Andric            LVElement *Element = nullptr);
14206c3fb27SDimitry Andric   void add(uint32_t StreamIdx, TypeIndex TI, StringRef Name);
14306c3fb27SDimitry Andric   LVElement *find(uint32_t StreamIdx, TypeIndex TI, bool Create = true);
14406c3fb27SDimitry Andric   TypeIndex find(uint32_t StreamIdx, StringRef Name);
14506c3fb27SDimitry Andric };
14606c3fb27SDimitry Andric 
14706c3fb27SDimitry Andric class LVForwardReferences {
14806c3fb27SDimitry Andric   // Forward reference and its definitions (Name as key).
14906c3fb27SDimitry Andric   using ForwardEntry = std::pair<TypeIndex, TypeIndex>;
15006c3fb27SDimitry Andric   using ForwardTypeNames = std::map<StringRef, ForwardEntry>;
15106c3fb27SDimitry Andric   ForwardTypeNames ForwardTypesNames;
15206c3fb27SDimitry Andric 
15306c3fb27SDimitry Andric   // Forward reference and its definition (TypeIndex as key).
15406c3fb27SDimitry Andric   using ForwardType = std::map<TypeIndex, TypeIndex>;
15506c3fb27SDimitry Andric   ForwardType ForwardTypes;
15606c3fb27SDimitry Andric 
15706c3fb27SDimitry Andric   // Forward types and its references.
add(TypeIndex TIForward,TypeIndex TIReference)15806c3fb27SDimitry Andric   void add(TypeIndex TIForward, TypeIndex TIReference) {
15906c3fb27SDimitry Andric     ForwardTypes.emplace(TIForward, TIReference);
16006c3fb27SDimitry Andric   }
16106c3fb27SDimitry Andric 
add(StringRef Name,TypeIndex TIForward)16206c3fb27SDimitry Andric   void add(StringRef Name, TypeIndex TIForward) {
16306c3fb27SDimitry Andric     if (ForwardTypesNames.find(Name) == ForwardTypesNames.end()) {
16406c3fb27SDimitry Andric       ForwardTypesNames.emplace(
16506c3fb27SDimitry Andric           std::piecewise_construct, std::forward_as_tuple(Name),
16606c3fb27SDimitry Andric           std::forward_as_tuple(TIForward, TypeIndex::None()));
16706c3fb27SDimitry Andric     } else {
16806c3fb27SDimitry Andric       // Update a recorded definition with its reference.
16906c3fb27SDimitry Andric       ForwardTypesNames[Name].first = TIForward;
17006c3fb27SDimitry Andric       add(TIForward, ForwardTypesNames[Name].second);
17106c3fb27SDimitry Andric     }
17206c3fb27SDimitry Andric   }
17306c3fb27SDimitry Andric 
17406c3fb27SDimitry Andric   // Update a previously recorded forward reference with its definition.
update(StringRef Name,TypeIndex TIReference)17506c3fb27SDimitry Andric   void update(StringRef Name, TypeIndex TIReference) {
17606c3fb27SDimitry Andric     if (ForwardTypesNames.find(Name) != ForwardTypesNames.end()) {
17706c3fb27SDimitry Andric       // Update the recorded forward reference with its definition.
17806c3fb27SDimitry Andric       ForwardTypesNames[Name].second = TIReference;
17906c3fb27SDimitry Andric       add(ForwardTypesNames[Name].first, TIReference);
18006c3fb27SDimitry Andric     } else {
18106c3fb27SDimitry Andric       // We have not seen the forward reference. Insert the definition.
18206c3fb27SDimitry Andric       ForwardTypesNames.emplace(
18306c3fb27SDimitry Andric           std::piecewise_construct, std::forward_as_tuple(Name),
18406c3fb27SDimitry Andric           std::forward_as_tuple(TypeIndex::None(), TIReference));
18506c3fb27SDimitry Andric     }
18606c3fb27SDimitry Andric   }
18706c3fb27SDimitry Andric 
18806c3fb27SDimitry Andric public:
18906c3fb27SDimitry Andric   LVForwardReferences() = default;
19006c3fb27SDimitry Andric 
record(bool IsForwardRef,StringRef Name,TypeIndex TI)19106c3fb27SDimitry Andric   void record(bool IsForwardRef, StringRef Name, TypeIndex TI) {
19206c3fb27SDimitry Andric     // We are expecting for the forward references to be first. But that
19306c3fb27SDimitry Andric     // is not always the case. A name must be recorded regardless of the
19406c3fb27SDimitry Andric     // order in which the forward reference appears.
19506c3fb27SDimitry Andric     (IsForwardRef) ? add(Name, TI) : update(Name, TI);
19606c3fb27SDimitry Andric   }
19706c3fb27SDimitry Andric 
find(TypeIndex TIForward)19806c3fb27SDimitry Andric   TypeIndex find(TypeIndex TIForward) {
19906c3fb27SDimitry Andric     return (ForwardTypes.find(TIForward) != ForwardTypes.end())
20006c3fb27SDimitry Andric                ? ForwardTypes[TIForward]
20106c3fb27SDimitry Andric                : TypeIndex::None();
20206c3fb27SDimitry Andric   }
20306c3fb27SDimitry Andric 
find(StringRef Name)20406c3fb27SDimitry Andric   TypeIndex find(StringRef Name) {
20506c3fb27SDimitry Andric     return (ForwardTypesNames.find(Name) != ForwardTypesNames.end())
20606c3fb27SDimitry Andric                ? ForwardTypesNames[Name].second
20706c3fb27SDimitry Andric                : TypeIndex::None();
20806c3fb27SDimitry Andric   }
20906c3fb27SDimitry Andric 
21006c3fb27SDimitry Andric   // If the given TI corresponds to a reference, return the reference.
21106c3fb27SDimitry Andric   // Otherwise return the given TI.
remap(TypeIndex TI)21206c3fb27SDimitry Andric   TypeIndex remap(TypeIndex TI) {
21306c3fb27SDimitry Andric     TypeIndex Forward = find(TI);
21406c3fb27SDimitry Andric     return Forward.isNoneType() ? TI : Forward;
21506c3fb27SDimitry Andric   }
21606c3fb27SDimitry Andric };
21706c3fb27SDimitry Andric 
21806c3fb27SDimitry Andric // Namespace deduction.
21906c3fb27SDimitry Andric class LVNamespaceDeduction {
22006c3fb27SDimitry Andric   LVShared *Shared = nullptr;
22106c3fb27SDimitry Andric 
22206c3fb27SDimitry Andric   using Names = std::map<StringRef, LVScope *>;
22306c3fb27SDimitry Andric   Names NamespaceNames;
22406c3fb27SDimitry Andric 
22506c3fb27SDimitry Andric   using LookupSet = std::set<StringRef>;
22606c3fb27SDimitry Andric   LookupSet DeducedScopes;
22706c3fb27SDimitry Andric   LookupSet UnresolvedScopes;
22806c3fb27SDimitry Andric   LookupSet IdentifiedNamespaces;
22906c3fb27SDimitry Andric 
add(StringRef Name,LVScope * Namespace)23006c3fb27SDimitry Andric   void add(StringRef Name, LVScope *Namespace) {
23106c3fb27SDimitry Andric     if (NamespaceNames.find(Name) == NamespaceNames.end())
23206c3fb27SDimitry Andric       NamespaceNames.emplace(Name, Namespace);
23306c3fb27SDimitry Andric   }
23406c3fb27SDimitry Andric 
23506c3fb27SDimitry Andric public:
LVNamespaceDeduction(LVShared * Shared)23606c3fb27SDimitry Andric   LVNamespaceDeduction(LVShared *Shared) : Shared(Shared) {}
23706c3fb27SDimitry Andric 
23806c3fb27SDimitry Andric   void init();
23906c3fb27SDimitry Andric   void add(StringRef String);
24006c3fb27SDimitry Andric   LVScope *get(LVStringRefs Components);
24106c3fb27SDimitry Andric   LVScope *get(StringRef Name, bool CheckScope = true);
24206c3fb27SDimitry Andric 
24306c3fb27SDimitry Andric   // Find the logical namespace for the 'Name' component.
find(StringRef Name)24406c3fb27SDimitry Andric   LVScope *find(StringRef Name) {
24506c3fb27SDimitry Andric     LVScope *Namespace = (NamespaceNames.find(Name) != NamespaceNames.end())
24606c3fb27SDimitry Andric                              ? NamespaceNames[Name]
24706c3fb27SDimitry Andric                              : nullptr;
24806c3fb27SDimitry Andric     return Namespace;
24906c3fb27SDimitry Andric   }
25006c3fb27SDimitry Andric 
25106c3fb27SDimitry Andric   // For the given lexical components, return a tuple with the first entry
25206c3fb27SDimitry Andric   // being the outermost namespace and the second entry being the first
25306c3fb27SDimitry Andric   // non-namespace.
find(LVStringRefs Components)25406c3fb27SDimitry Andric   LVLexicalIndex find(LVStringRefs Components) {
25506c3fb27SDimitry Andric     if (Components.empty())
25606c3fb27SDimitry Andric       return {};
25706c3fb27SDimitry Andric 
25806c3fb27SDimitry Andric     LVStringRefs::size_type FirstNamespace = 0;
25906c3fb27SDimitry Andric     LVStringRefs::size_type FirstNonNamespace;
26006c3fb27SDimitry Andric     for (LVStringRefs::size_type Index = 0; Index < Components.size();
26106c3fb27SDimitry Andric          ++Index) {
26206c3fb27SDimitry Andric       FirstNonNamespace = Index;
26306c3fb27SDimitry Andric       LookupSet::iterator Iter = IdentifiedNamespaces.find(Components[Index]);
26406c3fb27SDimitry Andric       if (Iter == IdentifiedNamespaces.end())
26506c3fb27SDimitry Andric         // The component is not a namespace name.
26606c3fb27SDimitry Andric         break;
26706c3fb27SDimitry Andric     }
26806c3fb27SDimitry Andric     return std::make_tuple(FirstNamespace, FirstNonNamespace);
26906c3fb27SDimitry Andric   }
27006c3fb27SDimitry Andric };
27106c3fb27SDimitry Andric 
27206c3fb27SDimitry Andric // Strings.
27306c3fb27SDimitry Andric class LVStringRecords {
27406c3fb27SDimitry Andric   using StringEntry = std::tuple<uint32_t, std::string, LVScopeCompileUnit *>;
27506c3fb27SDimitry Andric   using StringIds = std::map<TypeIndex, StringEntry>;
27606c3fb27SDimitry Andric   StringIds Strings;
27706c3fb27SDimitry Andric 
27806c3fb27SDimitry Andric public:
27906c3fb27SDimitry Andric   LVStringRecords() = default;
28006c3fb27SDimitry Andric 
add(TypeIndex TI,StringRef String)28106c3fb27SDimitry Andric   void add(TypeIndex TI, StringRef String) {
28206c3fb27SDimitry Andric     static uint32_t Index = 0;
28306c3fb27SDimitry Andric     if (Strings.find(TI) == Strings.end())
28406c3fb27SDimitry Andric       Strings.emplace(
28506c3fb27SDimitry Andric           std::piecewise_construct, std::forward_as_tuple(TI),
28606c3fb27SDimitry Andric           std::forward_as_tuple(++Index, std::string(String), nullptr));
28706c3fb27SDimitry Andric   }
28806c3fb27SDimitry Andric 
find(TypeIndex TI)28906c3fb27SDimitry Andric   StringRef find(TypeIndex TI) {
29006c3fb27SDimitry Andric     StringIds::iterator Iter = Strings.find(TI);
29106c3fb27SDimitry Andric     return Iter != Strings.end() ? std::get<1>(Iter->second) : StringRef{};
29206c3fb27SDimitry Andric   }
29306c3fb27SDimitry Andric 
findIndex(TypeIndex TI)29406c3fb27SDimitry Andric   uint32_t findIndex(TypeIndex TI) {
29506c3fb27SDimitry Andric     StringIds::iterator Iter = Strings.find(TI);
29606c3fb27SDimitry Andric     return Iter != Strings.end() ? std::get<0>(Iter->second) : 0;
29706c3fb27SDimitry Andric   }
29806c3fb27SDimitry Andric 
29906c3fb27SDimitry Andric   // Move strings representing the filenames to the compile unit.
30006c3fb27SDimitry Andric   void addFilenames();
30106c3fb27SDimitry Andric   void addFilenames(LVScopeCompileUnit *Scope);
30206c3fb27SDimitry Andric };
30306c3fb27SDimitry Andric } // namespace
30406c3fb27SDimitry Andric 
30506c3fb27SDimitry Andric using LVTypeKinds = std::set<TypeLeafKind>;
30606c3fb27SDimitry Andric using LVSymbolKinds = std::set<SymbolKind>;
30706c3fb27SDimitry Andric 
30806c3fb27SDimitry Andric // The following data keeps forward information, type records, names for
30906c3fb27SDimitry Andric // namespace deduction, strings records, line records.
31006c3fb27SDimitry Andric // It is shared by the type visitor, symbol visitor and logical visitor and
31106c3fb27SDimitry Andric // it is independent from the CodeViewReader.
31206c3fb27SDimitry Andric struct LVShared {
31306c3fb27SDimitry Andric   LVCodeViewReader *Reader;
31406c3fb27SDimitry Andric   LVLogicalVisitor *Visitor;
31506c3fb27SDimitry Andric   LVForwardReferences ForwardReferences;
31606c3fb27SDimitry Andric   LVLineRecords LineRecords;
31706c3fb27SDimitry Andric   LVNamespaceDeduction NamespaceDeduction;
31806c3fb27SDimitry Andric   LVStringRecords StringRecords;
31906c3fb27SDimitry Andric   LVTypeRecords TypeRecords;
32006c3fb27SDimitry Andric 
32106c3fb27SDimitry Andric   // In order to determine which types and/or symbols records should be handled
32206c3fb27SDimitry Andric   // by the reader, we record record kinds seen by the type and symbol visitors.
32306c3fb27SDimitry Andric   // At the end of the scopes creation, the '--internal=tag' option will allow
32406c3fb27SDimitry Andric   // to print the unique record ids collected.
32506c3fb27SDimitry Andric   LVTypeKinds TypeKinds;
32606c3fb27SDimitry Andric   LVSymbolKinds SymbolKinds;
32706c3fb27SDimitry Andric 
LVSharedllvm::logicalview::LVShared32806c3fb27SDimitry Andric   LVShared(LVCodeViewReader *Reader, LVLogicalVisitor *Visitor)
32906c3fb27SDimitry Andric       : Reader(Reader), Visitor(Visitor), NamespaceDeduction(this),
33006c3fb27SDimitry Andric         TypeRecords(this) {}
33106c3fb27SDimitry Andric   ~LVShared() = default;
33206c3fb27SDimitry Andric };
33306c3fb27SDimitry Andric } // namespace logicalview
33406c3fb27SDimitry Andric } // namespace llvm
33506c3fb27SDimitry Andric 
add(uint32_t StreamIdx,TypeIndex TI,TypeLeafKind Kind,LVElement * Element)33606c3fb27SDimitry Andric void LVTypeRecords::add(uint32_t StreamIdx, TypeIndex TI, TypeLeafKind Kind,
33706c3fb27SDimitry Andric                         LVElement *Element) {
33806c3fb27SDimitry Andric   RecordTable &Target =
33906c3fb27SDimitry Andric       (StreamIdx == StreamTPI) ? RecordFromTypes : RecordFromIds;
34006c3fb27SDimitry Andric   Target.emplace(std::piecewise_construct, std::forward_as_tuple(TI),
34106c3fb27SDimitry Andric                  std::forward_as_tuple(Kind, Element));
34206c3fb27SDimitry Andric }
34306c3fb27SDimitry Andric 
add(uint32_t StreamIdx,TypeIndex TI,StringRef Name)34406c3fb27SDimitry Andric void LVTypeRecords::add(uint32_t StreamIdx, TypeIndex TI, StringRef Name) {
34506c3fb27SDimitry Andric   NameTable &Target = (StreamIdx == StreamTPI) ? NameFromTypes : NameFromIds;
34606c3fb27SDimitry Andric   Target.emplace(Name, TI);
34706c3fb27SDimitry Andric }
34806c3fb27SDimitry Andric 
find(uint32_t StreamIdx,TypeIndex TI,bool Create)34906c3fb27SDimitry Andric LVElement *LVTypeRecords::find(uint32_t StreamIdx, TypeIndex TI, bool Create) {
35006c3fb27SDimitry Andric   RecordTable &Target =
35106c3fb27SDimitry Andric       (StreamIdx == StreamTPI) ? RecordFromTypes : RecordFromIds;
35206c3fb27SDimitry Andric 
35306c3fb27SDimitry Andric   LVElement *Element = nullptr;
35406c3fb27SDimitry Andric   RecordTable::iterator Iter = Target.find(TI);
35506c3fb27SDimitry Andric   if (Iter != Target.end()) {
35606c3fb27SDimitry Andric     Element = Iter->second.second;
35706c3fb27SDimitry Andric     if (Element || !Create)
35806c3fb27SDimitry Andric       return Element;
35906c3fb27SDimitry Andric 
36006c3fb27SDimitry Andric     // Create the logical element if not found.
36106c3fb27SDimitry Andric     Element = Shared->Visitor->createElement(Iter->second.first);
36206c3fb27SDimitry Andric     if (Element) {
36306c3fb27SDimitry Andric       Element->setOffset(TI.getIndex());
36406c3fb27SDimitry Andric       Element->setOffsetFromTypeIndex();
36506c3fb27SDimitry Andric       Target[TI].second = Element;
36606c3fb27SDimitry Andric     }
36706c3fb27SDimitry Andric   }
36806c3fb27SDimitry Andric   return Element;
36906c3fb27SDimitry Andric }
37006c3fb27SDimitry Andric 
find(uint32_t StreamIdx,StringRef Name)37106c3fb27SDimitry Andric TypeIndex LVTypeRecords::find(uint32_t StreamIdx, StringRef Name) {
37206c3fb27SDimitry Andric   NameTable &Target = (StreamIdx == StreamTPI) ? NameFromTypes : NameFromIds;
37306c3fb27SDimitry Andric   NameTable::iterator Iter = Target.find(Name);
37406c3fb27SDimitry Andric   return Iter != Target.end() ? Iter->second : TypeIndex::None();
37506c3fb27SDimitry Andric }
37606c3fb27SDimitry Andric 
addFilenames()37706c3fb27SDimitry Andric void LVStringRecords::addFilenames() {
37806c3fb27SDimitry Andric   for (StringIds::const_reference Entry : Strings) {
37906c3fb27SDimitry Andric     StringRef Name = std::get<1>(Entry.second);
38006c3fb27SDimitry Andric     LVScopeCompileUnit *Scope = std::get<2>(Entry.second);
38106c3fb27SDimitry Andric     Scope->addFilename(transformPath(Name));
38206c3fb27SDimitry Andric   }
38306c3fb27SDimitry Andric   Strings.clear();
38406c3fb27SDimitry Andric }
38506c3fb27SDimitry Andric 
addFilenames(LVScopeCompileUnit * Scope)38606c3fb27SDimitry Andric void LVStringRecords::addFilenames(LVScopeCompileUnit *Scope) {
38706c3fb27SDimitry Andric   for (StringIds::reference Entry : Strings)
38806c3fb27SDimitry Andric     if (!std::get<2>(Entry.second))
38906c3fb27SDimitry Andric       std::get<2>(Entry.second) = Scope;
39006c3fb27SDimitry Andric }
39106c3fb27SDimitry Andric 
add(StringRef String)39206c3fb27SDimitry Andric void LVNamespaceDeduction::add(StringRef String) {
39306c3fb27SDimitry Andric   StringRef InnerComponent;
39406c3fb27SDimitry Andric   StringRef OuterComponent;
39506c3fb27SDimitry Andric   std::tie(OuterComponent, InnerComponent) = getInnerComponent(String);
39606c3fb27SDimitry Andric   DeducedScopes.insert(InnerComponent);
39706c3fb27SDimitry Andric   if (OuterComponent.size())
39806c3fb27SDimitry Andric     UnresolvedScopes.insert(OuterComponent);
39906c3fb27SDimitry Andric }
40006c3fb27SDimitry Andric 
init()40106c3fb27SDimitry Andric void LVNamespaceDeduction::init() {
40206c3fb27SDimitry Andric   // We have 2 sets of names:
40306c3fb27SDimitry Andric   // - deduced scopes (class, structure, union and enum) and
40406c3fb27SDimitry Andric   // - unresolved scopes, that can represent namespaces or any deduced.
40506c3fb27SDimitry Andric   // Before creating the namespaces, we have to traverse the unresolved
40606c3fb27SDimitry Andric   // and remove any references to already deduced scopes.
40706c3fb27SDimitry Andric   LVStringRefs Components;
40806c3fb27SDimitry Andric   for (const StringRef &Unresolved : UnresolvedScopes) {
40906c3fb27SDimitry Andric     Components = getAllLexicalComponents(Unresolved);
41006c3fb27SDimitry Andric     for (const StringRef &Component : Components) {
41106c3fb27SDimitry Andric       LookupSet::iterator Iter = DeducedScopes.find(Component);
41206c3fb27SDimitry Andric       if (Iter == DeducedScopes.end())
41306c3fb27SDimitry Andric         IdentifiedNamespaces.insert(Component);
41406c3fb27SDimitry Andric     }
41506c3fb27SDimitry Andric   }
41606c3fb27SDimitry Andric 
41706c3fb27SDimitry Andric   LLVM_DEBUG({
41806c3fb27SDimitry Andric     auto Print = [&](LookupSet &Container, const char *Title) {
41906c3fb27SDimitry Andric       auto Header = [&]() {
42006c3fb27SDimitry Andric         dbgs() << formatv("\n{0}\n", fmt_repeat('=', 72));
42106c3fb27SDimitry Andric         dbgs() << formatv("{0}\n", Title);
42206c3fb27SDimitry Andric         dbgs() << formatv("{0}\n", fmt_repeat('=', 72));
42306c3fb27SDimitry Andric       };
42406c3fb27SDimitry Andric       Header();
42506c3fb27SDimitry Andric       for (const StringRef &Item : Container)
42606c3fb27SDimitry Andric         dbgs() << formatv("'{0}'\n", Item.str().c_str());
42706c3fb27SDimitry Andric     };
42806c3fb27SDimitry Andric 
42906c3fb27SDimitry Andric     Print(DeducedScopes, "Deducted Scopes");
43006c3fb27SDimitry Andric     Print(UnresolvedScopes, "Unresolved Scopes");
43106c3fb27SDimitry Andric     Print(IdentifiedNamespaces, "Namespaces");
43206c3fb27SDimitry Andric   });
43306c3fb27SDimitry Andric }
43406c3fb27SDimitry Andric 
get(LVStringRefs Components)43506c3fb27SDimitry Andric LVScope *LVNamespaceDeduction::get(LVStringRefs Components) {
43606c3fb27SDimitry Andric   LLVM_DEBUG({
43706c3fb27SDimitry Andric     for (const StringRef &Component : Components)
43806c3fb27SDimitry Andric       dbgs() << formatv("'{0}'\n", Component.str().c_str());
43906c3fb27SDimitry Andric   });
44006c3fb27SDimitry Andric 
44106c3fb27SDimitry Andric   if (Components.empty())
44206c3fb27SDimitry Andric     return nullptr;
44306c3fb27SDimitry Andric 
44406c3fb27SDimitry Andric   // Update the namespaces relationship.
44506c3fb27SDimitry Andric   LVScope *Namespace = nullptr;
44606c3fb27SDimitry Andric   LVScope *Parent = Shared->Reader->getCompileUnit();
44706c3fb27SDimitry Andric   for (const StringRef &Component : Components) {
44806c3fb27SDimitry Andric     // Check if we have seen the namespace.
44906c3fb27SDimitry Andric     Namespace = find(Component);
45006c3fb27SDimitry Andric     if (!Namespace) {
45106c3fb27SDimitry Andric       // We have identified namespaces that are generated by MSVC. Mark them
45206c3fb27SDimitry Andric       // as 'system' so they will be excluded from the logical view.
45306c3fb27SDimitry Andric       Namespace = Shared->Reader->createScopeNamespace();
45406c3fb27SDimitry Andric       Namespace->setTag(dwarf::DW_TAG_namespace);
45506c3fb27SDimitry Andric       Namespace->setName(Component);
45606c3fb27SDimitry Andric       Parent->addElement(Namespace);
45706c3fb27SDimitry Andric       getReader().isSystemEntry(Namespace);
45806c3fb27SDimitry Andric       add(Component, Namespace);
45906c3fb27SDimitry Andric     }
46006c3fb27SDimitry Andric     Parent = Namespace;
46106c3fb27SDimitry Andric   }
46206c3fb27SDimitry Andric   return Parent;
46306c3fb27SDimitry Andric }
46406c3fb27SDimitry Andric 
get(StringRef ScopedName,bool CheckScope)46506c3fb27SDimitry Andric LVScope *LVNamespaceDeduction::get(StringRef ScopedName, bool CheckScope) {
46606c3fb27SDimitry Andric   LVStringRefs Components = getAllLexicalComponents(ScopedName);
46706c3fb27SDimitry Andric   if (CheckScope)
468*5f757f3fSDimitry Andric     llvm::erase_if(Components, [&](StringRef Component) {
469*5f757f3fSDimitry Andric       LookupSet::iterator Iter = IdentifiedNamespaces.find(Component);
47006c3fb27SDimitry Andric       return Iter == IdentifiedNamespaces.end();
471*5f757f3fSDimitry Andric     });
47206c3fb27SDimitry Andric 
47306c3fb27SDimitry Andric   LLVM_DEBUG(
47406c3fb27SDimitry Andric       { dbgs() << formatv("ScopedName: '{0}'\n", ScopedName.str().c_str()); });
47506c3fb27SDimitry Andric 
47606c3fb27SDimitry Andric   return get(Components);
47706c3fb27SDimitry Andric }
47806c3fb27SDimitry Andric 
47906c3fb27SDimitry Andric #undef DEBUG_TYPE
48006c3fb27SDimitry Andric #define DEBUG_TYPE "CodeViewTypeVisitor"
48106c3fb27SDimitry Andric 
48206c3fb27SDimitry Andric //===----------------------------------------------------------------------===//
48306c3fb27SDimitry Andric // TypeRecord traversal.
48406c3fb27SDimitry Andric //===----------------------------------------------------------------------===//
printTypeIndex(StringRef FieldName,TypeIndex TI,uint32_t StreamIdx) const48506c3fb27SDimitry Andric void LVTypeVisitor::printTypeIndex(StringRef FieldName, TypeIndex TI,
48606c3fb27SDimitry Andric                                    uint32_t StreamIdx) const {
48706c3fb27SDimitry Andric   codeview::printTypeIndex(W, FieldName, TI,
48806c3fb27SDimitry Andric                            StreamIdx == StreamTPI ? Types : Ids);
48906c3fb27SDimitry Andric }
49006c3fb27SDimitry Andric 
visitTypeBegin(CVType & Record)49106c3fb27SDimitry Andric Error LVTypeVisitor::visitTypeBegin(CVType &Record) {
49206c3fb27SDimitry Andric   return visitTypeBegin(Record, TypeIndex::fromArrayIndex(Types.size()));
49306c3fb27SDimitry Andric }
49406c3fb27SDimitry Andric 
visitTypeBegin(CVType & Record,TypeIndex TI)49506c3fb27SDimitry Andric Error LVTypeVisitor::visitTypeBegin(CVType &Record, TypeIndex TI) {
49606c3fb27SDimitry Andric   LLVM_DEBUG({
49706c3fb27SDimitry Andric     W.getOStream() << formatTypeLeafKind(Record.kind());
49806c3fb27SDimitry Andric     W.getOStream() << " (" << HexNumber(TI.getIndex()) << ")\n";
49906c3fb27SDimitry Andric   });
50006c3fb27SDimitry Andric 
50106c3fb27SDimitry Andric   if (options().getInternalTag())
50206c3fb27SDimitry Andric     Shared->TypeKinds.insert(Record.kind());
50306c3fb27SDimitry Andric 
50406c3fb27SDimitry Andric   // The collected type records, will be use to create the logical elements
50506c3fb27SDimitry Andric   // during the symbols traversal when a type is referenced.
50606c3fb27SDimitry Andric   CurrentTypeIndex = TI;
50706c3fb27SDimitry Andric   Shared->TypeRecords.add(StreamIdx, TI, Record.kind());
50806c3fb27SDimitry Andric   return Error::success();
50906c3fb27SDimitry Andric }
51006c3fb27SDimitry Andric 
visitUnknownType(CVType & Record)51106c3fb27SDimitry Andric Error LVTypeVisitor::visitUnknownType(CVType &Record) {
51206c3fb27SDimitry Andric   LLVM_DEBUG({ W.printNumber("Length", uint32_t(Record.content().size())); });
51306c3fb27SDimitry Andric   return Error::success();
51406c3fb27SDimitry Andric }
51506c3fb27SDimitry Andric 
visitMemberBegin(CVMemberRecord & Record)51606c3fb27SDimitry Andric Error LVTypeVisitor::visitMemberBegin(CVMemberRecord &Record) {
51706c3fb27SDimitry Andric   LLVM_DEBUG({
51806c3fb27SDimitry Andric     W.startLine() << formatTypeLeafKind(Record.Kind);
51906c3fb27SDimitry Andric     W.getOStream() << " {\n";
52006c3fb27SDimitry Andric     W.indent();
52106c3fb27SDimitry Andric   });
52206c3fb27SDimitry Andric   return Error::success();
52306c3fb27SDimitry Andric }
52406c3fb27SDimitry Andric 
visitMemberEnd(CVMemberRecord & Record)52506c3fb27SDimitry Andric Error LVTypeVisitor::visitMemberEnd(CVMemberRecord &Record) {
52606c3fb27SDimitry Andric   LLVM_DEBUG({
52706c3fb27SDimitry Andric     W.unindent();
52806c3fb27SDimitry Andric     W.startLine() << "}\n";
52906c3fb27SDimitry Andric   });
53006c3fb27SDimitry Andric   return Error::success();
53106c3fb27SDimitry Andric }
53206c3fb27SDimitry Andric 
visitUnknownMember(CVMemberRecord & Record)53306c3fb27SDimitry Andric Error LVTypeVisitor::visitUnknownMember(CVMemberRecord &Record) {
53406c3fb27SDimitry Andric   LLVM_DEBUG({ W.printHex("UnknownMember", unsigned(Record.Kind)); });
53506c3fb27SDimitry Andric   return Error::success();
53606c3fb27SDimitry Andric }
53706c3fb27SDimitry Andric 
53806c3fb27SDimitry Andric // LF_BUILDINFO (TPI)/(IPI)
visitKnownRecord(CVType & Record,BuildInfoRecord & Args)53906c3fb27SDimitry Andric Error LVTypeVisitor::visitKnownRecord(CVType &Record, BuildInfoRecord &Args) {
54006c3fb27SDimitry Andric   // All the args are references into the TPI/IPI stream.
54106c3fb27SDimitry Andric   LLVM_DEBUG({
54206c3fb27SDimitry Andric     W.printNumber("NumArgs", static_cast<uint32_t>(Args.getArgs().size()));
54306c3fb27SDimitry Andric     ListScope Arguments(W, "Arguments");
54406c3fb27SDimitry Andric     for (TypeIndex Arg : Args.getArgs())
54506c3fb27SDimitry Andric       printTypeIndex("ArgType", Arg, StreamIPI);
54606c3fb27SDimitry Andric   });
54706c3fb27SDimitry Andric 
54806c3fb27SDimitry Andric   // Only add the strings that hold information about filenames. They will be
54906c3fb27SDimitry Andric   // used to complete the line/file information for the logical elements.
55006c3fb27SDimitry Andric   // There are other strings holding information about namespaces.
55106c3fb27SDimitry Andric   TypeIndex TI;
55206c3fb27SDimitry Andric   StringRef String;
55306c3fb27SDimitry Andric 
55406c3fb27SDimitry Andric   // Absolute CWD path
55506c3fb27SDimitry Andric   TI = Args.getArgs()[BuildInfoRecord::BuildInfoArg::CurrentDirectory];
55606c3fb27SDimitry Andric   String = Ids.getTypeName(TI);
55706c3fb27SDimitry Andric   if (!String.empty())
55806c3fb27SDimitry Andric     Shared->StringRecords.add(TI, String);
55906c3fb27SDimitry Andric 
56006c3fb27SDimitry Andric   // Get the compile unit name.
56106c3fb27SDimitry Andric   TI = Args.getArgs()[BuildInfoRecord::BuildInfoArg::SourceFile];
56206c3fb27SDimitry Andric   String = Ids.getTypeName(TI);
56306c3fb27SDimitry Andric   if (!String.empty())
56406c3fb27SDimitry Andric     Shared->StringRecords.add(TI, String);
56506c3fb27SDimitry Andric   LogicalVisitor->setCompileUnitName(std::string(String));
56606c3fb27SDimitry Andric 
56706c3fb27SDimitry Andric   return Error::success();
56806c3fb27SDimitry Andric }
56906c3fb27SDimitry Andric 
57006c3fb27SDimitry Andric // LF_CLASS, LF_STRUCTURE, LF_INTERFACE (TPI)
visitKnownRecord(CVType & Record,ClassRecord & Class)57106c3fb27SDimitry Andric Error LVTypeVisitor::visitKnownRecord(CVType &Record, ClassRecord &Class) {
57206c3fb27SDimitry Andric   LLVM_DEBUG({
57306c3fb27SDimitry Andric     printTypeIndex("TypeIndex", CurrentTypeIndex, StreamTPI);
57406c3fb27SDimitry Andric     printTypeIndex("FieldListType", Class.getFieldList(), StreamTPI);
57506c3fb27SDimitry Andric     W.printString("Name", Class.getName());
57606c3fb27SDimitry Andric   });
57706c3fb27SDimitry Andric 
57806c3fb27SDimitry Andric   // Collect class name for scope deduction.
57906c3fb27SDimitry Andric   Shared->NamespaceDeduction.add(Class.getName());
58006c3fb27SDimitry Andric   Shared->ForwardReferences.record(Class.isForwardRef(), Class.getName(),
58106c3fb27SDimitry Andric                                    CurrentTypeIndex);
58206c3fb27SDimitry Andric 
58306c3fb27SDimitry Andric   // Collect class name for contained scopes deduction.
58406c3fb27SDimitry Andric   Shared->TypeRecords.add(StreamIdx, CurrentTypeIndex, Class.getName());
58506c3fb27SDimitry Andric   return Error::success();
58606c3fb27SDimitry Andric }
58706c3fb27SDimitry Andric 
58806c3fb27SDimitry Andric // LF_ENUM (TPI)
visitKnownRecord(CVType & Record,EnumRecord & Enum)58906c3fb27SDimitry Andric Error LVTypeVisitor::visitKnownRecord(CVType &Record, EnumRecord &Enum) {
59006c3fb27SDimitry Andric   LLVM_DEBUG({
59106c3fb27SDimitry Andric     printTypeIndex("TypeIndex", CurrentTypeIndex, StreamTPI);
59206c3fb27SDimitry Andric     printTypeIndex("FieldListType", Enum.getFieldList(), StreamTPI);
59306c3fb27SDimitry Andric     W.printString("Name", Enum.getName());
59406c3fb27SDimitry Andric   });
59506c3fb27SDimitry Andric 
59606c3fb27SDimitry Andric   // Collect enum name for scope deduction.
59706c3fb27SDimitry Andric   Shared->NamespaceDeduction.add(Enum.getName());
59806c3fb27SDimitry Andric   return Error::success();
59906c3fb27SDimitry Andric }
60006c3fb27SDimitry Andric 
60106c3fb27SDimitry Andric // LF_FUNC_ID (TPI)/(IPI)
visitKnownRecord(CVType & Record,FuncIdRecord & Func)60206c3fb27SDimitry Andric Error LVTypeVisitor::visitKnownRecord(CVType &Record, FuncIdRecord &Func) {
60306c3fb27SDimitry Andric   LLVM_DEBUG({
60406c3fb27SDimitry Andric     printTypeIndex("TypeIndex", CurrentTypeIndex, StreamTPI);
60506c3fb27SDimitry Andric     printTypeIndex("Type", Func.getFunctionType(), StreamTPI);
60606c3fb27SDimitry Andric     printTypeIndex("Parent", Func.getParentScope(), StreamTPI);
60706c3fb27SDimitry Andric     W.printString("Name", Func.getName());
60806c3fb27SDimitry Andric   });
60906c3fb27SDimitry Andric 
61006c3fb27SDimitry Andric   // Collect function name for scope deduction.
61106c3fb27SDimitry Andric   Shared->NamespaceDeduction.add(Func.getName());
61206c3fb27SDimitry Andric   return Error::success();
61306c3fb27SDimitry Andric }
61406c3fb27SDimitry Andric 
61506c3fb27SDimitry Andric // LF_PROCEDURE (TPI)
visitKnownRecord(CVType & Record,ProcedureRecord & Proc)61606c3fb27SDimitry Andric Error LVTypeVisitor::visitKnownRecord(CVType &Record, ProcedureRecord &Proc) {
61706c3fb27SDimitry Andric   LLVM_DEBUG({
61806c3fb27SDimitry Andric     printTypeIndex("TypeIndex", CurrentTypeIndex, StreamTPI);
61906c3fb27SDimitry Andric     printTypeIndex("ReturnType", Proc.getReturnType(), StreamTPI);
62006c3fb27SDimitry Andric     W.printNumber("NumParameters", Proc.getParameterCount());
62106c3fb27SDimitry Andric     printTypeIndex("ArgListType", Proc.getArgumentList(), StreamTPI);
62206c3fb27SDimitry Andric   });
62306c3fb27SDimitry Andric 
62406c3fb27SDimitry Andric   // Collect procedure information as they can be referenced by typedefs.
62506c3fb27SDimitry Andric   Shared->TypeRecords.add(StreamTPI, CurrentTypeIndex, {});
62606c3fb27SDimitry Andric   return Error::success();
62706c3fb27SDimitry Andric }
62806c3fb27SDimitry Andric 
62906c3fb27SDimitry Andric // LF_STRING_ID (TPI)/(IPI)
visitKnownRecord(CVType & Record,StringIdRecord & String)63006c3fb27SDimitry Andric Error LVTypeVisitor::visitKnownRecord(CVType &Record, StringIdRecord &String) {
63106c3fb27SDimitry Andric   // No additional references are needed.
63206c3fb27SDimitry Andric   LLVM_DEBUG({
63306c3fb27SDimitry Andric     printTypeIndex("Id", String.getId(), StreamIPI);
63406c3fb27SDimitry Andric     W.printString("StringData", String.getString());
63506c3fb27SDimitry Andric   });
63606c3fb27SDimitry Andric   return Error::success();
63706c3fb27SDimitry Andric }
63806c3fb27SDimitry Andric 
63906c3fb27SDimitry Andric // LF_UDT_SRC_LINE (TPI)/(IPI)
visitKnownRecord(CVType & Record,UdtSourceLineRecord & Line)64006c3fb27SDimitry Andric Error LVTypeVisitor::visitKnownRecord(CVType &Record,
64106c3fb27SDimitry Andric                                       UdtSourceLineRecord &Line) {
64206c3fb27SDimitry Andric   // UDT and SourceFile are references into the TPI/IPI stream.
64306c3fb27SDimitry Andric   LLVM_DEBUG({
64406c3fb27SDimitry Andric     printTypeIndex("UDT", Line.getUDT(), StreamIPI);
64506c3fb27SDimitry Andric     printTypeIndex("SourceFile", Line.getSourceFile(), StreamIPI);
64606c3fb27SDimitry Andric     W.printNumber("LineNumber", Line.getLineNumber());
64706c3fb27SDimitry Andric   });
64806c3fb27SDimitry Andric 
64906c3fb27SDimitry Andric   Shared->LineRecords.push_back(CurrentTypeIndex);
65006c3fb27SDimitry Andric   return Error::success();
65106c3fb27SDimitry Andric }
65206c3fb27SDimitry Andric 
65306c3fb27SDimitry Andric // LF_UNION (TPI)
visitKnownRecord(CVType & Record,UnionRecord & Union)65406c3fb27SDimitry Andric Error LVTypeVisitor::visitKnownRecord(CVType &Record, UnionRecord &Union) {
65506c3fb27SDimitry Andric   LLVM_DEBUG({
65606c3fb27SDimitry Andric     W.printNumber("MemberCount", Union.getMemberCount());
65706c3fb27SDimitry Andric     printTypeIndex("FieldList", Union.getFieldList(), StreamTPI);
65806c3fb27SDimitry Andric     W.printNumber("SizeOf", Union.getSize());
65906c3fb27SDimitry Andric     W.printString("Name", Union.getName());
66006c3fb27SDimitry Andric     if (Union.hasUniqueName())
66106c3fb27SDimitry Andric       W.printString("UniqueName", Union.getUniqueName());
66206c3fb27SDimitry Andric   });
66306c3fb27SDimitry Andric 
66406c3fb27SDimitry Andric   // Collect union name for scope deduction.
66506c3fb27SDimitry Andric   Shared->NamespaceDeduction.add(Union.getName());
66606c3fb27SDimitry Andric   Shared->ForwardReferences.record(Union.isForwardRef(), Union.getName(),
66706c3fb27SDimitry Andric                                    CurrentTypeIndex);
66806c3fb27SDimitry Andric 
66906c3fb27SDimitry Andric   // Collect class name for contained scopes deduction.
67006c3fb27SDimitry Andric   Shared->TypeRecords.add(StreamIdx, CurrentTypeIndex, Union.getName());
67106c3fb27SDimitry Andric   return Error::success();
67206c3fb27SDimitry Andric }
67306c3fb27SDimitry Andric 
67406c3fb27SDimitry Andric #undef DEBUG_TYPE
67506c3fb27SDimitry Andric #define DEBUG_TYPE "CodeViewSymbolVisitor"
67606c3fb27SDimitry Andric 
67706c3fb27SDimitry Andric //===----------------------------------------------------------------------===//
67806c3fb27SDimitry Andric // SymbolRecord traversal.
67906c3fb27SDimitry Andric //===----------------------------------------------------------------------===//
printRelocatedField(StringRef Label,uint32_t RelocOffset,uint32_t Offset,StringRef * RelocSym)68006c3fb27SDimitry Andric void LVSymbolVisitorDelegate::printRelocatedField(StringRef Label,
68106c3fb27SDimitry Andric                                                   uint32_t RelocOffset,
68206c3fb27SDimitry Andric                                                   uint32_t Offset,
68306c3fb27SDimitry Andric                                                   StringRef *RelocSym) {
68406c3fb27SDimitry Andric   Reader->printRelocatedField(Label, CoffSection, RelocOffset, Offset,
68506c3fb27SDimitry Andric                               RelocSym);
68606c3fb27SDimitry Andric }
68706c3fb27SDimitry Andric 
getLinkageName(uint32_t RelocOffset,uint32_t Offset,StringRef * RelocSym)68806c3fb27SDimitry Andric void LVSymbolVisitorDelegate::getLinkageName(uint32_t RelocOffset,
68906c3fb27SDimitry Andric                                              uint32_t Offset,
69006c3fb27SDimitry Andric                                              StringRef *RelocSym) {
69106c3fb27SDimitry Andric   Reader->getLinkageName(CoffSection, RelocOffset, Offset, RelocSym);
69206c3fb27SDimitry Andric }
69306c3fb27SDimitry Andric 
69406c3fb27SDimitry Andric StringRef
getFileNameForFileOffset(uint32_t FileOffset)69506c3fb27SDimitry Andric LVSymbolVisitorDelegate::getFileNameForFileOffset(uint32_t FileOffset) {
69606c3fb27SDimitry Andric   Expected<StringRef> Name = Reader->getFileNameForFileOffset(FileOffset);
69706c3fb27SDimitry Andric   if (!Name) {
69806c3fb27SDimitry Andric     consumeError(Name.takeError());
69906c3fb27SDimitry Andric     return {};
70006c3fb27SDimitry Andric   }
70106c3fb27SDimitry Andric   return *Name;
70206c3fb27SDimitry Andric }
70306c3fb27SDimitry Andric 
getStringTable()70406c3fb27SDimitry Andric DebugStringTableSubsectionRef LVSymbolVisitorDelegate::getStringTable() {
70506c3fb27SDimitry Andric   return Reader->CVStringTable;
70606c3fb27SDimitry Andric }
70706c3fb27SDimitry Andric 
printLocalVariableAddrRange(const LocalVariableAddrRange & Range,uint32_t RelocationOffset)70806c3fb27SDimitry Andric void LVSymbolVisitor::printLocalVariableAddrRange(
70906c3fb27SDimitry Andric     const LocalVariableAddrRange &Range, uint32_t RelocationOffset) {
71006c3fb27SDimitry Andric   DictScope S(W, "LocalVariableAddrRange");
71106c3fb27SDimitry Andric   if (ObjDelegate)
71206c3fb27SDimitry Andric     ObjDelegate->printRelocatedField("OffsetStart", RelocationOffset,
71306c3fb27SDimitry Andric                                      Range.OffsetStart);
71406c3fb27SDimitry Andric   W.printHex("ISectStart", Range.ISectStart);
71506c3fb27SDimitry Andric   W.printHex("Range", Range.Range);
71606c3fb27SDimitry Andric }
71706c3fb27SDimitry Andric 
printLocalVariableAddrGap(ArrayRef<LocalVariableAddrGap> Gaps)71806c3fb27SDimitry Andric void LVSymbolVisitor::printLocalVariableAddrGap(
71906c3fb27SDimitry Andric     ArrayRef<LocalVariableAddrGap> Gaps) {
72006c3fb27SDimitry Andric   for (const LocalVariableAddrGap &Gap : Gaps) {
72106c3fb27SDimitry Andric     ListScope S(W, "LocalVariableAddrGap");
72206c3fb27SDimitry Andric     W.printHex("GapStartOffset", Gap.GapStartOffset);
72306c3fb27SDimitry Andric     W.printHex("Range", Gap.Range);
72406c3fb27SDimitry Andric   }
72506c3fb27SDimitry Andric }
72606c3fb27SDimitry Andric 
printTypeIndex(StringRef FieldName,TypeIndex TI) const72706c3fb27SDimitry Andric void LVSymbolVisitor::printTypeIndex(StringRef FieldName, TypeIndex TI) const {
72806c3fb27SDimitry Andric   codeview::printTypeIndex(W, FieldName, TI, Types);
72906c3fb27SDimitry Andric }
73006c3fb27SDimitry Andric 
visitSymbolBegin(CVSymbol & Record)73106c3fb27SDimitry Andric Error LVSymbolVisitor::visitSymbolBegin(CVSymbol &Record) {
73206c3fb27SDimitry Andric   return visitSymbolBegin(Record, 0);
73306c3fb27SDimitry Andric }
73406c3fb27SDimitry Andric 
visitSymbolBegin(CVSymbol & Record,uint32_t Offset)73506c3fb27SDimitry Andric Error LVSymbolVisitor::visitSymbolBegin(CVSymbol &Record, uint32_t Offset) {
73606c3fb27SDimitry Andric   SymbolKind Kind = Record.kind();
73706c3fb27SDimitry Andric   LLVM_DEBUG({
73806c3fb27SDimitry Andric     W.printNumber("Offset", Offset);
73906c3fb27SDimitry Andric     W.printEnum("Begin Kind", unsigned(Kind), getSymbolTypeNames());
74006c3fb27SDimitry Andric   });
74106c3fb27SDimitry Andric 
74206c3fb27SDimitry Andric   if (options().getInternalTag())
74306c3fb27SDimitry Andric     Shared->SymbolKinds.insert(Kind);
74406c3fb27SDimitry Andric 
74506c3fb27SDimitry Andric   LogicalVisitor->CurrentElement = LogicalVisitor->createElement(Kind);
74606c3fb27SDimitry Andric   if (!LogicalVisitor->CurrentElement) {
74706c3fb27SDimitry Andric     LLVM_DEBUG({
74806c3fb27SDimitry Andric         // We have an unsupported Symbol or Type Record.
74906c3fb27SDimitry Andric         // W.printEnum("Kind ignored", unsigned(Kind), getSymbolTypeNames());
75006c3fb27SDimitry Andric     });
75106c3fb27SDimitry Andric     return Error::success();
75206c3fb27SDimitry Andric   }
75306c3fb27SDimitry Andric 
75406c3fb27SDimitry Andric   // Offset carried by the traversal routines when dealing with streams.
75506c3fb27SDimitry Andric   CurrentOffset = Offset;
75606c3fb27SDimitry Andric   IsCompileUnit = false;
75706c3fb27SDimitry Andric   if (!LogicalVisitor->CurrentElement->getOffsetFromTypeIndex())
75806c3fb27SDimitry Andric     LogicalVisitor->CurrentElement->setOffset(Offset);
75906c3fb27SDimitry Andric   if (symbolOpensScope(Kind) || (IsCompileUnit = symbolIsCompileUnit(Kind))) {
76006c3fb27SDimitry Andric     assert(LogicalVisitor->CurrentScope && "Invalid scope!");
76106c3fb27SDimitry Andric     LogicalVisitor->addElement(LogicalVisitor->CurrentScope, IsCompileUnit);
76206c3fb27SDimitry Andric   } else {
76306c3fb27SDimitry Andric     if (LogicalVisitor->CurrentSymbol)
76406c3fb27SDimitry Andric       LogicalVisitor->addElement(LogicalVisitor->CurrentSymbol);
76506c3fb27SDimitry Andric     if (LogicalVisitor->CurrentType)
76606c3fb27SDimitry Andric       LogicalVisitor->addElement(LogicalVisitor->CurrentType);
76706c3fb27SDimitry Andric   }
76806c3fb27SDimitry Andric 
76906c3fb27SDimitry Andric   return Error::success();
77006c3fb27SDimitry Andric }
77106c3fb27SDimitry Andric 
visitSymbolEnd(CVSymbol & Record)77206c3fb27SDimitry Andric Error LVSymbolVisitor::visitSymbolEnd(CVSymbol &Record) {
77306c3fb27SDimitry Andric   SymbolKind Kind = Record.kind();
77406c3fb27SDimitry Andric   LLVM_DEBUG(
77506c3fb27SDimitry Andric       { W.printEnum("End Kind", unsigned(Kind), getSymbolTypeNames()); });
77606c3fb27SDimitry Andric 
77706c3fb27SDimitry Andric   if (symbolEndsScope(Kind)) {
77806c3fb27SDimitry Andric     LogicalVisitor->popScope();
77906c3fb27SDimitry Andric   }
78006c3fb27SDimitry Andric 
78106c3fb27SDimitry Andric   return Error::success();
78206c3fb27SDimitry Andric }
78306c3fb27SDimitry Andric 
visitUnknownSymbol(CVSymbol & Record)78406c3fb27SDimitry Andric Error LVSymbolVisitor::visitUnknownSymbol(CVSymbol &Record) {
78506c3fb27SDimitry Andric   LLVM_DEBUG({ W.printNumber("Length", Record.length()); });
78606c3fb27SDimitry Andric   return Error::success();
78706c3fb27SDimitry Andric }
78806c3fb27SDimitry Andric 
78906c3fb27SDimitry Andric // S_BLOCK32
visitKnownRecord(CVSymbol & Record,BlockSym & Block)79006c3fb27SDimitry Andric Error LVSymbolVisitor::visitKnownRecord(CVSymbol &Record, BlockSym &Block) {
79106c3fb27SDimitry Andric   LLVM_DEBUG({
79206c3fb27SDimitry Andric     W.printHex("CodeSize", Block.CodeSize);
79306c3fb27SDimitry Andric     W.printHex("Segment", Block.Segment);
79406c3fb27SDimitry Andric     W.printString("BlockName", Block.Name);
79506c3fb27SDimitry Andric   });
79606c3fb27SDimitry Andric 
79706c3fb27SDimitry Andric   if (LVScope *Scope = LogicalVisitor->CurrentScope) {
79806c3fb27SDimitry Andric     StringRef LinkageName;
79906c3fb27SDimitry Andric     if (ObjDelegate)
80006c3fb27SDimitry Andric       ObjDelegate->getLinkageName(Block.getRelocationOffset(), Block.CodeOffset,
80106c3fb27SDimitry Andric                                   &LinkageName);
80206c3fb27SDimitry Andric     Scope->setLinkageName(LinkageName);
80306c3fb27SDimitry Andric 
80406c3fb27SDimitry Andric     if (options().getGeneralCollectRanges()) {
80506c3fb27SDimitry Andric       // Record converted segment::offset addressing for this scope.
80606c3fb27SDimitry Andric       LVAddress Addendum = Reader->getSymbolTableAddress(LinkageName);
80706c3fb27SDimitry Andric       LVAddress LowPC =
80806c3fb27SDimitry Andric           Reader->linearAddress(Block.Segment, Block.CodeOffset, Addendum);
80906c3fb27SDimitry Andric       LVAddress HighPC = LowPC + Block.CodeSize - 1;
81006c3fb27SDimitry Andric       Scope->addObject(LowPC, HighPC);
81106c3fb27SDimitry Andric     }
81206c3fb27SDimitry Andric   }
81306c3fb27SDimitry Andric 
81406c3fb27SDimitry Andric   return Error::success();
81506c3fb27SDimitry Andric }
81606c3fb27SDimitry Andric 
81706c3fb27SDimitry Andric // S_BPREL32
visitKnownRecord(CVSymbol & Record,BPRelativeSym & Local)81806c3fb27SDimitry Andric Error LVSymbolVisitor::visitKnownRecord(CVSymbol &Record,
81906c3fb27SDimitry Andric                                         BPRelativeSym &Local) {
82006c3fb27SDimitry Andric   LLVM_DEBUG({
82106c3fb27SDimitry Andric     printTypeIndex("Type", Local.Type);
82206c3fb27SDimitry Andric     W.printNumber("Offset", Local.Offset);
82306c3fb27SDimitry Andric     W.printString("VarName", Local.Name);
82406c3fb27SDimitry Andric   });
82506c3fb27SDimitry Andric 
82606c3fb27SDimitry Andric   if (LVSymbol *Symbol = LogicalVisitor->CurrentSymbol) {
82706c3fb27SDimitry Andric     Symbol->setName(Local.Name);
82806c3fb27SDimitry Andric     // From the MS_Symbol_Type.pdf documentation (S_BPREL32):
82906c3fb27SDimitry Andric     // This symbol specifies symbols that are allocated on the stack for a
83006c3fb27SDimitry Andric     // procedure. For C and C++, these include the actual function parameters
83106c3fb27SDimitry Andric     // and the local non-static variables of functions.
83206c3fb27SDimitry Andric     // However, the offset for 'this' comes as a negative value.
83306c3fb27SDimitry Andric 
83406c3fb27SDimitry Andric     // Symbol was created as 'variable'; determine its real kind.
83506c3fb27SDimitry Andric     Symbol->resetIsVariable();
83606c3fb27SDimitry Andric 
83706c3fb27SDimitry Andric     if (Local.Name.equals("this")) {
83806c3fb27SDimitry Andric       Symbol->setIsParameter();
83906c3fb27SDimitry Andric       Symbol->setIsArtificial();
84006c3fb27SDimitry Andric     } else {
84106c3fb27SDimitry Andric       // Determine symbol kind.
84206c3fb27SDimitry Andric       bool(Local.Offset > 0) ? Symbol->setIsParameter()
84306c3fb27SDimitry Andric                              : Symbol->setIsVariable();
84406c3fb27SDimitry Andric     }
84506c3fb27SDimitry Andric 
84606c3fb27SDimitry Andric     // Update correct debug information tag.
84706c3fb27SDimitry Andric     if (Symbol->getIsParameter())
84806c3fb27SDimitry Andric       Symbol->setTag(dwarf::DW_TAG_formal_parameter);
84906c3fb27SDimitry Andric 
85006c3fb27SDimitry Andric     LVElement *Element = LogicalVisitor->getElement(StreamTPI, Local.Type);
85106c3fb27SDimitry Andric     if (Element && Element->getIsScoped()) {
85206c3fb27SDimitry Andric       // We have a local type. Find its parent function.
85306c3fb27SDimitry Andric       LVScope *Parent = Symbol->getFunctionParent();
85406c3fb27SDimitry Andric       // The element representing the type has been already finalized. If
85506c3fb27SDimitry Andric       // the type is an aggregate type, its members have been already added.
85606c3fb27SDimitry Andric       // As the type is local, its level will be changed.
85706c3fb27SDimitry Andric 
85806c3fb27SDimitry Andric       // FIXME: Currently the algorithm used to scope lambda functions is
85906c3fb27SDimitry Andric       // incorrect. Before we allocate the type at this scope, check if is
86006c3fb27SDimitry Andric       // already allocated in other scope.
86106c3fb27SDimitry Andric       if (!Element->getParentScope()) {
86206c3fb27SDimitry Andric         Parent->addElement(Element);
86306c3fb27SDimitry Andric         Element->updateLevel(Parent);
86406c3fb27SDimitry Andric       }
86506c3fb27SDimitry Andric     }
86606c3fb27SDimitry Andric     Symbol->setType(Element);
86706c3fb27SDimitry Andric   }
86806c3fb27SDimitry Andric 
86906c3fb27SDimitry Andric   return Error::success();
87006c3fb27SDimitry Andric }
87106c3fb27SDimitry Andric 
87206c3fb27SDimitry Andric // S_REGREL32
visitKnownRecord(CVSymbol & Record,RegRelativeSym & Local)87306c3fb27SDimitry Andric Error LVSymbolVisitor::visitKnownRecord(CVSymbol &Record,
87406c3fb27SDimitry Andric                                         RegRelativeSym &Local) {
87506c3fb27SDimitry Andric   LLVM_DEBUG({
87606c3fb27SDimitry Andric     printTypeIndex("Type", Local.Type);
87706c3fb27SDimitry Andric     W.printNumber("Offset", Local.Offset);
87806c3fb27SDimitry Andric     W.printString("VarName", Local.Name);
87906c3fb27SDimitry Andric   });
88006c3fb27SDimitry Andric 
88106c3fb27SDimitry Andric   if (LVSymbol *Symbol = LogicalVisitor->CurrentSymbol) {
88206c3fb27SDimitry Andric     Symbol->setName(Local.Name);
88306c3fb27SDimitry Andric 
88406c3fb27SDimitry Andric     // Symbol was created as 'variable'; determine its real kind.
88506c3fb27SDimitry Andric     Symbol->resetIsVariable();
88606c3fb27SDimitry Andric 
88706c3fb27SDimitry Andric     // Check for the 'this' symbol.
88806c3fb27SDimitry Andric     if (Local.Name.equals("this")) {
88906c3fb27SDimitry Andric       Symbol->setIsArtificial();
89006c3fb27SDimitry Andric       Symbol->setIsParameter();
89106c3fb27SDimitry Andric     } else {
89206c3fb27SDimitry Andric       // Determine symbol kind.
89306c3fb27SDimitry Andric       determineSymbolKind(Symbol, Local.Register);
89406c3fb27SDimitry Andric     }
89506c3fb27SDimitry Andric 
89606c3fb27SDimitry Andric     // Update correct debug information tag.
89706c3fb27SDimitry Andric     if (Symbol->getIsParameter())
89806c3fb27SDimitry Andric       Symbol->setTag(dwarf::DW_TAG_formal_parameter);
89906c3fb27SDimitry Andric 
90006c3fb27SDimitry Andric     LVElement *Element = LogicalVisitor->getElement(StreamTPI, Local.Type);
90106c3fb27SDimitry Andric     if (Element && Element->getIsScoped()) {
90206c3fb27SDimitry Andric       // We have a local type. Find its parent function.
90306c3fb27SDimitry Andric       LVScope *Parent = Symbol->getFunctionParent();
90406c3fb27SDimitry Andric       // The element representing the type has been already finalized. If
90506c3fb27SDimitry Andric       // the type is an aggregate type, its members have been already added.
90606c3fb27SDimitry Andric       // As the type is local, its level will be changed.
90706c3fb27SDimitry Andric 
90806c3fb27SDimitry Andric       // FIXME: Currently the algorithm used to scope lambda functions is
90906c3fb27SDimitry Andric       // incorrect. Before we allocate the type at this scope, check if is
91006c3fb27SDimitry Andric       // already allocated in other scope.
91106c3fb27SDimitry Andric       if (!Element->getParentScope()) {
91206c3fb27SDimitry Andric         Parent->addElement(Element);
91306c3fb27SDimitry Andric         Element->updateLevel(Parent);
91406c3fb27SDimitry Andric       }
91506c3fb27SDimitry Andric     }
91606c3fb27SDimitry Andric     Symbol->setType(Element);
91706c3fb27SDimitry Andric   }
91806c3fb27SDimitry Andric 
91906c3fb27SDimitry Andric   return Error::success();
92006c3fb27SDimitry Andric }
92106c3fb27SDimitry Andric 
92206c3fb27SDimitry Andric // S_BUILDINFO
visitKnownRecord(CVSymbol & CVR,BuildInfoSym & BuildInfo)92306c3fb27SDimitry Andric Error LVSymbolVisitor::visitKnownRecord(CVSymbol &CVR,
92406c3fb27SDimitry Andric                                         BuildInfoSym &BuildInfo) {
92506c3fb27SDimitry Andric   LLVM_DEBUG({ printTypeIndex("BuildId", BuildInfo.BuildId); });
92606c3fb27SDimitry Andric 
92706c3fb27SDimitry Andric   CVType CVBuildType = Ids.getType(BuildInfo.BuildId);
92806c3fb27SDimitry Andric   if (Error Err = LogicalVisitor->finishVisitation(
92906c3fb27SDimitry Andric           CVBuildType, BuildInfo.BuildId, Reader->getCompileUnit()))
93006c3fb27SDimitry Andric     return Err;
93106c3fb27SDimitry Andric 
93206c3fb27SDimitry Andric   return Error::success();
93306c3fb27SDimitry Andric }
93406c3fb27SDimitry Andric 
93506c3fb27SDimitry Andric // S_COMPILE2
visitKnownRecord(CVSymbol & Record,Compile2Sym & Compile2)93606c3fb27SDimitry Andric Error LVSymbolVisitor::visitKnownRecord(CVSymbol &Record,
93706c3fb27SDimitry Andric                                         Compile2Sym &Compile2) {
93806c3fb27SDimitry Andric   LLVM_DEBUG({
93906c3fb27SDimitry Andric     W.printEnum("Language", uint8_t(Compile2.getLanguage()),
94006c3fb27SDimitry Andric                 getSourceLanguageNames());
94106c3fb27SDimitry Andric     W.printFlags("Flags", uint32_t(Compile2.getFlags()),
94206c3fb27SDimitry Andric                  getCompileSym3FlagNames());
94306c3fb27SDimitry Andric     W.printEnum("Machine", unsigned(Compile2.Machine), getCPUTypeNames());
94406c3fb27SDimitry Andric     W.printString("VersionName", Compile2.Version);
94506c3fb27SDimitry Andric   });
94606c3fb27SDimitry Andric 
94706c3fb27SDimitry Andric   // MSVC generates the following sequence for a CodeView module:
94806c3fb27SDimitry Andric   //   S_OBJNAME    --> Set 'CurrentObjectName'.
94906c3fb27SDimitry Andric   //   S_COMPILE2   --> Set the compile unit name using 'CurrentObjectName'.
95006c3fb27SDimitry Andric   //   ...
95106c3fb27SDimitry Andric   //   S_BUILDINFO  --> Extract the source name.
95206c3fb27SDimitry Andric   //
95306c3fb27SDimitry Andric   // Clang generates the following sequence for a CodeView module:
95406c3fb27SDimitry Andric   //   S_COMPILE2   --> Set the compile unit name to empty string.
95506c3fb27SDimitry Andric   //   ...
95606c3fb27SDimitry Andric   //   S_BUILDINFO  --> Extract the source name.
95706c3fb27SDimitry Andric   //
95806c3fb27SDimitry Andric   // For both toolchains, update the compile unit name from S_BUILDINFO.
95906c3fb27SDimitry Andric   if (LVScope *Scope = LogicalVisitor->CurrentScope) {
96006c3fb27SDimitry Andric     // The name of the CU, was extracted from the 'BuildInfo' subsection.
96106c3fb27SDimitry Andric     Reader->setCompileUnitCPUType(Compile2.Machine);
96206c3fb27SDimitry Andric     Scope->setName(CurrentObjectName);
96306c3fb27SDimitry Andric     if (options().getAttributeProducer())
96406c3fb27SDimitry Andric       Scope->setProducer(Compile2.Version);
96506c3fb27SDimitry Andric     getReader().isSystemEntry(Scope, CurrentObjectName);
96606c3fb27SDimitry Andric 
96706c3fb27SDimitry Andric     // The line records in CodeView are recorded per Module ID. Update
96806c3fb27SDimitry Andric     // the relationship between the current CU and the Module ID.
96906c3fb27SDimitry Andric     Reader->addModule(Scope);
97006c3fb27SDimitry Andric 
97106c3fb27SDimitry Andric     // Updated the collected strings with their associated compile unit.
97206c3fb27SDimitry Andric     Shared->StringRecords.addFilenames(Reader->getCompileUnit());
97306c3fb27SDimitry Andric   }
97406c3fb27SDimitry Andric 
97506c3fb27SDimitry Andric   // Clear any previous ObjectName.
97606c3fb27SDimitry Andric   CurrentObjectName = "";
97706c3fb27SDimitry Andric   return Error::success();
97806c3fb27SDimitry Andric }
97906c3fb27SDimitry Andric 
98006c3fb27SDimitry Andric // S_COMPILE3
visitKnownRecord(CVSymbol & Record,Compile3Sym & Compile3)98106c3fb27SDimitry Andric Error LVSymbolVisitor::visitKnownRecord(CVSymbol &Record,
98206c3fb27SDimitry Andric                                         Compile3Sym &Compile3) {
98306c3fb27SDimitry Andric   LLVM_DEBUG({
98406c3fb27SDimitry Andric     W.printEnum("Language", uint8_t(Compile3.getLanguage()),
98506c3fb27SDimitry Andric                 getSourceLanguageNames());
98606c3fb27SDimitry Andric     W.printFlags("Flags", uint32_t(Compile3.getFlags()),
98706c3fb27SDimitry Andric                  getCompileSym3FlagNames());
98806c3fb27SDimitry Andric     W.printEnum("Machine", unsigned(Compile3.Machine), getCPUTypeNames());
98906c3fb27SDimitry Andric     W.printString("VersionName", Compile3.Version);
99006c3fb27SDimitry Andric   });
99106c3fb27SDimitry Andric 
99206c3fb27SDimitry Andric   // MSVC generates the following sequence for a CodeView module:
99306c3fb27SDimitry Andric   //   S_OBJNAME    --> Set 'CurrentObjectName'.
99406c3fb27SDimitry Andric   //   S_COMPILE3   --> Set the compile unit name using 'CurrentObjectName'.
99506c3fb27SDimitry Andric   //   ...
99606c3fb27SDimitry Andric   //   S_BUILDINFO  --> Extract the source name.
99706c3fb27SDimitry Andric   //
99806c3fb27SDimitry Andric   // Clang generates the following sequence for a CodeView module:
99906c3fb27SDimitry Andric   //   S_COMPILE3   --> Set the compile unit name to empty string.
100006c3fb27SDimitry Andric   //   ...
100106c3fb27SDimitry Andric   //   S_BUILDINFO  --> Extract the source name.
100206c3fb27SDimitry Andric   //
100306c3fb27SDimitry Andric   // For both toolchains, update the compile unit name from S_BUILDINFO.
100406c3fb27SDimitry Andric   if (LVScope *Scope = LogicalVisitor->CurrentScope) {
100506c3fb27SDimitry Andric     // The name of the CU, was extracted from the 'BuildInfo' subsection.
100606c3fb27SDimitry Andric     Reader->setCompileUnitCPUType(Compile3.Machine);
100706c3fb27SDimitry Andric     Scope->setName(CurrentObjectName);
100806c3fb27SDimitry Andric     if (options().getAttributeProducer())
100906c3fb27SDimitry Andric       Scope->setProducer(Compile3.Version);
101006c3fb27SDimitry Andric     getReader().isSystemEntry(Scope, CurrentObjectName);
101106c3fb27SDimitry Andric 
101206c3fb27SDimitry Andric     // The line records in CodeView are recorded per Module ID. Update
101306c3fb27SDimitry Andric     // the relationship between the current CU and the Module ID.
101406c3fb27SDimitry Andric     Reader->addModule(Scope);
101506c3fb27SDimitry Andric 
101606c3fb27SDimitry Andric     // Updated the collected strings with their associated compile unit.
101706c3fb27SDimitry Andric     Shared->StringRecords.addFilenames(Reader->getCompileUnit());
101806c3fb27SDimitry Andric   }
101906c3fb27SDimitry Andric 
102006c3fb27SDimitry Andric   // Clear any previous ObjectName.
102106c3fb27SDimitry Andric   CurrentObjectName = "";
102206c3fb27SDimitry Andric   return Error::success();
102306c3fb27SDimitry Andric }
102406c3fb27SDimitry Andric 
102506c3fb27SDimitry Andric // S_CONSTANT, S_MANCONSTANT
visitKnownRecord(CVSymbol & Record,ConstantSym & Constant)102606c3fb27SDimitry Andric Error LVSymbolVisitor::visitKnownRecord(CVSymbol &Record,
102706c3fb27SDimitry Andric                                         ConstantSym &Constant) {
102806c3fb27SDimitry Andric   LLVM_DEBUG({
102906c3fb27SDimitry Andric     printTypeIndex("Type", Constant.Type);
103006c3fb27SDimitry Andric     W.printNumber("Value", Constant.Value);
103106c3fb27SDimitry Andric     W.printString("Name", Constant.Name);
103206c3fb27SDimitry Andric   });
103306c3fb27SDimitry Andric 
103406c3fb27SDimitry Andric   if (LVSymbol *Symbol = LogicalVisitor->CurrentSymbol) {
103506c3fb27SDimitry Andric     Symbol->setName(Constant.Name);
103606c3fb27SDimitry Andric     Symbol->setType(LogicalVisitor->getElement(StreamTPI, Constant.Type));
103706c3fb27SDimitry Andric     Symbol->resetIncludeInPrint();
103806c3fb27SDimitry Andric   }
103906c3fb27SDimitry Andric 
104006c3fb27SDimitry Andric   return Error::success();
104106c3fb27SDimitry Andric }
104206c3fb27SDimitry Andric 
104306c3fb27SDimitry Andric // S_DEFRANGE_FRAMEPOINTER_REL_FULL_SCOPE
visitKnownRecord(CVSymbol & Record,DefRangeFramePointerRelFullScopeSym & DefRangeFramePointerRelFullScope)104406c3fb27SDimitry Andric Error LVSymbolVisitor::visitKnownRecord(
104506c3fb27SDimitry Andric     CVSymbol &Record,
104606c3fb27SDimitry Andric     DefRangeFramePointerRelFullScopeSym &DefRangeFramePointerRelFullScope) {
104706c3fb27SDimitry Andric   // DefRanges don't have types, just registers and code offsets.
104806c3fb27SDimitry Andric   LLVM_DEBUG({
104906c3fb27SDimitry Andric     if (LocalSymbol)
105006c3fb27SDimitry Andric       W.getOStream() << formatv("Symbol: {0}, ", LocalSymbol->getName());
105106c3fb27SDimitry Andric 
105206c3fb27SDimitry Andric     W.printNumber("Offset", DefRangeFramePointerRelFullScope.Offset);
105306c3fb27SDimitry Andric   });
105406c3fb27SDimitry Andric 
105506c3fb27SDimitry Andric   if (LVSymbol *Symbol = LocalSymbol) {
105606c3fb27SDimitry Andric     Symbol->setHasCodeViewLocation();
105706c3fb27SDimitry Andric     LocalSymbol = nullptr;
105806c3fb27SDimitry Andric 
105906c3fb27SDimitry Andric     // Add location debug location. Operands: [Offset, 0].
106006c3fb27SDimitry Andric     dwarf::Attribute Attr =
106106c3fb27SDimitry Andric         dwarf::Attribute(SymbolKind::S_DEFRANGE_FRAMEPOINTER_REL_FULL_SCOPE);
106206c3fb27SDimitry Andric 
106306c3fb27SDimitry Andric     uint64_t Operand1 = DefRangeFramePointerRelFullScope.Offset;
106406c3fb27SDimitry Andric     Symbol->addLocation(Attr, 0, 0, 0, 0);
106506c3fb27SDimitry Andric     Symbol->addLocationOperands(LVSmall(Attr), {Operand1});
106606c3fb27SDimitry Andric   }
106706c3fb27SDimitry Andric 
106806c3fb27SDimitry Andric   return Error::success();
106906c3fb27SDimitry Andric }
107006c3fb27SDimitry Andric 
107106c3fb27SDimitry Andric // S_DEFRANGE_FRAMEPOINTER_REL
visitKnownRecord(CVSymbol & Record,DefRangeFramePointerRelSym & DefRangeFramePointerRel)107206c3fb27SDimitry Andric Error LVSymbolVisitor::visitKnownRecord(
107306c3fb27SDimitry Andric     CVSymbol &Record, DefRangeFramePointerRelSym &DefRangeFramePointerRel) {
107406c3fb27SDimitry Andric   // DefRanges don't have types, just registers and code offsets.
107506c3fb27SDimitry Andric   LLVM_DEBUG({
107606c3fb27SDimitry Andric     if (LocalSymbol)
107706c3fb27SDimitry Andric       W.getOStream() << formatv("Symbol: {0}, ", LocalSymbol->getName());
107806c3fb27SDimitry Andric 
107906c3fb27SDimitry Andric     W.printNumber("Offset", DefRangeFramePointerRel.Hdr.Offset);
108006c3fb27SDimitry Andric     printLocalVariableAddrRange(DefRangeFramePointerRel.Range,
108106c3fb27SDimitry Andric                                 DefRangeFramePointerRel.getRelocationOffset());
108206c3fb27SDimitry Andric     printLocalVariableAddrGap(DefRangeFramePointerRel.Gaps);
108306c3fb27SDimitry Andric   });
108406c3fb27SDimitry Andric 
108506c3fb27SDimitry Andric   // We are expecting the following sequence:
108606c3fb27SDimitry Andric   //   128 | S_LOCAL [size = 20] `ParamBar`
108706c3fb27SDimitry Andric   //         ...
108806c3fb27SDimitry Andric   //   148 | S_DEFRANGE_FRAMEPOINTER_REL [size = 16]
108906c3fb27SDimitry Andric   if (LVSymbol *Symbol = LocalSymbol) {
109006c3fb27SDimitry Andric     Symbol->setHasCodeViewLocation();
109106c3fb27SDimitry Andric     LocalSymbol = nullptr;
109206c3fb27SDimitry Andric 
109306c3fb27SDimitry Andric     // Add location debug location. Operands: [Offset, 0].
109406c3fb27SDimitry Andric     dwarf::Attribute Attr =
109506c3fb27SDimitry Andric         dwarf::Attribute(SymbolKind::S_DEFRANGE_FRAMEPOINTER_REL);
109606c3fb27SDimitry Andric     uint64_t Operand1 = DefRangeFramePointerRel.Hdr.Offset;
109706c3fb27SDimitry Andric 
109806c3fb27SDimitry Andric     LocalVariableAddrRange Range = DefRangeFramePointerRel.Range;
109906c3fb27SDimitry Andric     LVAddress Address =
110006c3fb27SDimitry Andric         Reader->linearAddress(Range.ISectStart, Range.OffsetStart);
110106c3fb27SDimitry Andric 
110206c3fb27SDimitry Andric     Symbol->addLocation(Attr, Address, Address + Range.Range, 0, 0);
110306c3fb27SDimitry Andric     Symbol->addLocationOperands(LVSmall(Attr), {Operand1});
110406c3fb27SDimitry Andric   }
110506c3fb27SDimitry Andric 
110606c3fb27SDimitry Andric   return Error::success();
110706c3fb27SDimitry Andric }
110806c3fb27SDimitry Andric 
110906c3fb27SDimitry Andric // S_DEFRANGE_REGISTER_REL
visitKnownRecord(CVSymbol & Record,DefRangeRegisterRelSym & DefRangeRegisterRel)111006c3fb27SDimitry Andric Error LVSymbolVisitor::visitKnownRecord(
111106c3fb27SDimitry Andric     CVSymbol &Record, DefRangeRegisterRelSym &DefRangeRegisterRel) {
111206c3fb27SDimitry Andric   // DefRanges don't have types, just registers and code offsets.
111306c3fb27SDimitry Andric   LLVM_DEBUG({
111406c3fb27SDimitry Andric     if (LocalSymbol)
111506c3fb27SDimitry Andric       W.getOStream() << formatv("Symbol: {0}, ", LocalSymbol->getName());
111606c3fb27SDimitry Andric 
111706c3fb27SDimitry Andric     W.printBoolean("HasSpilledUDTMember",
111806c3fb27SDimitry Andric                    DefRangeRegisterRel.hasSpilledUDTMember());
111906c3fb27SDimitry Andric     W.printNumber("OffsetInParent", DefRangeRegisterRel.offsetInParent());
112006c3fb27SDimitry Andric     W.printNumber("BasePointerOffset",
112106c3fb27SDimitry Andric                   DefRangeRegisterRel.Hdr.BasePointerOffset);
112206c3fb27SDimitry Andric     printLocalVariableAddrRange(DefRangeRegisterRel.Range,
112306c3fb27SDimitry Andric                                 DefRangeRegisterRel.getRelocationOffset());
112406c3fb27SDimitry Andric     printLocalVariableAddrGap(DefRangeRegisterRel.Gaps);
112506c3fb27SDimitry Andric   });
112606c3fb27SDimitry Andric 
112706c3fb27SDimitry Andric   if (LVSymbol *Symbol = LocalSymbol) {
112806c3fb27SDimitry Andric     Symbol->setHasCodeViewLocation();
112906c3fb27SDimitry Andric     LocalSymbol = nullptr;
113006c3fb27SDimitry Andric 
113106c3fb27SDimitry Andric     // Add location debug location. Operands: [Register, Offset].
113206c3fb27SDimitry Andric     dwarf::Attribute Attr =
113306c3fb27SDimitry Andric         dwarf::Attribute(SymbolKind::S_DEFRANGE_REGISTER_REL);
113406c3fb27SDimitry Andric     uint64_t Operand1 = DefRangeRegisterRel.Hdr.Register;
113506c3fb27SDimitry Andric     uint64_t Operand2 = DefRangeRegisterRel.Hdr.BasePointerOffset;
113606c3fb27SDimitry Andric 
113706c3fb27SDimitry Andric     LocalVariableAddrRange Range = DefRangeRegisterRel.Range;
113806c3fb27SDimitry Andric     LVAddress Address =
113906c3fb27SDimitry Andric         Reader->linearAddress(Range.ISectStart, Range.OffsetStart);
114006c3fb27SDimitry Andric 
114106c3fb27SDimitry Andric     Symbol->addLocation(Attr, Address, Address + Range.Range, 0, 0);
114206c3fb27SDimitry Andric     Symbol->addLocationOperands(LVSmall(Attr), {Operand1, Operand2});
114306c3fb27SDimitry Andric   }
114406c3fb27SDimitry Andric 
114506c3fb27SDimitry Andric   return Error::success();
114606c3fb27SDimitry Andric }
114706c3fb27SDimitry Andric 
114806c3fb27SDimitry Andric // S_DEFRANGE_REGISTER
visitKnownRecord(CVSymbol & Record,DefRangeRegisterSym & DefRangeRegister)114906c3fb27SDimitry Andric Error LVSymbolVisitor::visitKnownRecord(CVSymbol &Record,
115006c3fb27SDimitry Andric                                         DefRangeRegisterSym &DefRangeRegister) {
115106c3fb27SDimitry Andric   // DefRanges don't have types, just registers and code offsets.
115206c3fb27SDimitry Andric   LLVM_DEBUG({
115306c3fb27SDimitry Andric     if (LocalSymbol)
115406c3fb27SDimitry Andric       W.getOStream() << formatv("Symbol: {0}, ", LocalSymbol->getName());
115506c3fb27SDimitry Andric 
115606c3fb27SDimitry Andric     W.printEnum("Register", uint16_t(DefRangeRegister.Hdr.Register),
115706c3fb27SDimitry Andric                 getRegisterNames(Reader->getCompileUnitCPUType()));
115806c3fb27SDimitry Andric     W.printNumber("MayHaveNoName", DefRangeRegister.Hdr.MayHaveNoName);
115906c3fb27SDimitry Andric     printLocalVariableAddrRange(DefRangeRegister.Range,
116006c3fb27SDimitry Andric                                 DefRangeRegister.getRelocationOffset());
116106c3fb27SDimitry Andric     printLocalVariableAddrGap(DefRangeRegister.Gaps);
116206c3fb27SDimitry Andric   });
116306c3fb27SDimitry Andric 
116406c3fb27SDimitry Andric   if (LVSymbol *Symbol = LocalSymbol) {
116506c3fb27SDimitry Andric     Symbol->setHasCodeViewLocation();
116606c3fb27SDimitry Andric     LocalSymbol = nullptr;
116706c3fb27SDimitry Andric 
116806c3fb27SDimitry Andric     // Add location debug location. Operands: [Register, 0].
116906c3fb27SDimitry Andric     dwarf::Attribute Attr = dwarf::Attribute(SymbolKind::S_DEFRANGE_REGISTER);
117006c3fb27SDimitry Andric     uint64_t Operand1 = DefRangeRegister.Hdr.Register;
117106c3fb27SDimitry Andric 
117206c3fb27SDimitry Andric     LocalVariableAddrRange Range = DefRangeRegister.Range;
117306c3fb27SDimitry Andric     LVAddress Address =
117406c3fb27SDimitry Andric         Reader->linearAddress(Range.ISectStart, Range.OffsetStart);
117506c3fb27SDimitry Andric 
117606c3fb27SDimitry Andric     Symbol->addLocation(Attr, Address, Address + Range.Range, 0, 0);
117706c3fb27SDimitry Andric     Symbol->addLocationOperands(LVSmall(Attr), {Operand1});
117806c3fb27SDimitry Andric   }
117906c3fb27SDimitry Andric 
118006c3fb27SDimitry Andric   return Error::success();
118106c3fb27SDimitry Andric }
118206c3fb27SDimitry Andric 
118306c3fb27SDimitry Andric // S_DEFRANGE_SUBFIELD_REGISTER
visitKnownRecord(CVSymbol & Record,DefRangeSubfieldRegisterSym & DefRangeSubfieldRegister)118406c3fb27SDimitry Andric Error LVSymbolVisitor::visitKnownRecord(
118506c3fb27SDimitry Andric     CVSymbol &Record, DefRangeSubfieldRegisterSym &DefRangeSubfieldRegister) {
118606c3fb27SDimitry Andric   // DefRanges don't have types, just registers and code offsets.
118706c3fb27SDimitry Andric   LLVM_DEBUG({
118806c3fb27SDimitry Andric     if (LocalSymbol)
118906c3fb27SDimitry Andric       W.getOStream() << formatv("Symbol: {0}, ", LocalSymbol->getName());
119006c3fb27SDimitry Andric 
119106c3fb27SDimitry Andric     W.printEnum("Register", uint16_t(DefRangeSubfieldRegister.Hdr.Register),
119206c3fb27SDimitry Andric                 getRegisterNames(Reader->getCompileUnitCPUType()));
119306c3fb27SDimitry Andric     W.printNumber("MayHaveNoName", DefRangeSubfieldRegister.Hdr.MayHaveNoName);
119406c3fb27SDimitry Andric     W.printNumber("OffsetInParent",
119506c3fb27SDimitry Andric                   DefRangeSubfieldRegister.Hdr.OffsetInParent);
119606c3fb27SDimitry Andric     printLocalVariableAddrRange(DefRangeSubfieldRegister.Range,
119706c3fb27SDimitry Andric                                 DefRangeSubfieldRegister.getRelocationOffset());
119806c3fb27SDimitry Andric     printLocalVariableAddrGap(DefRangeSubfieldRegister.Gaps);
119906c3fb27SDimitry Andric   });
120006c3fb27SDimitry Andric 
120106c3fb27SDimitry Andric   if (LVSymbol *Symbol = LocalSymbol) {
120206c3fb27SDimitry Andric     Symbol->setHasCodeViewLocation();
120306c3fb27SDimitry Andric     LocalSymbol = nullptr;
120406c3fb27SDimitry Andric 
120506c3fb27SDimitry Andric     // Add location debug location.  Operands: [Register, 0].
120606c3fb27SDimitry Andric     dwarf::Attribute Attr =
120706c3fb27SDimitry Andric         dwarf::Attribute(SymbolKind::S_DEFRANGE_SUBFIELD_REGISTER);
120806c3fb27SDimitry Andric     uint64_t Operand1 = DefRangeSubfieldRegister.Hdr.Register;
120906c3fb27SDimitry Andric 
121006c3fb27SDimitry Andric     LocalVariableAddrRange Range = DefRangeSubfieldRegister.Range;
121106c3fb27SDimitry Andric     LVAddress Address =
121206c3fb27SDimitry Andric         Reader->linearAddress(Range.ISectStart, Range.OffsetStart);
121306c3fb27SDimitry Andric 
121406c3fb27SDimitry Andric     Symbol->addLocation(Attr, Address, Address + Range.Range, 0, 0);
121506c3fb27SDimitry Andric     Symbol->addLocationOperands(LVSmall(Attr), {Operand1});
121606c3fb27SDimitry Andric   }
121706c3fb27SDimitry Andric 
121806c3fb27SDimitry Andric   return Error::success();
121906c3fb27SDimitry Andric }
122006c3fb27SDimitry Andric 
122106c3fb27SDimitry Andric // S_DEFRANGE_SUBFIELD
visitKnownRecord(CVSymbol & Record,DefRangeSubfieldSym & DefRangeSubfield)122206c3fb27SDimitry Andric Error LVSymbolVisitor::visitKnownRecord(CVSymbol &Record,
122306c3fb27SDimitry Andric                                         DefRangeSubfieldSym &DefRangeSubfield) {
122406c3fb27SDimitry Andric   // DefRanges don't have types, just registers and code offsets.
122506c3fb27SDimitry Andric   LLVM_DEBUG({
122606c3fb27SDimitry Andric     if (LocalSymbol)
122706c3fb27SDimitry Andric       W.getOStream() << formatv("Symbol: {0}, ", LocalSymbol->getName());
122806c3fb27SDimitry Andric 
122906c3fb27SDimitry Andric     if (ObjDelegate) {
123006c3fb27SDimitry Andric       DebugStringTableSubsectionRef Strings = ObjDelegate->getStringTable();
123106c3fb27SDimitry Andric       auto ExpectedProgram = Strings.getString(DefRangeSubfield.Program);
123206c3fb27SDimitry Andric       if (!ExpectedProgram) {
123306c3fb27SDimitry Andric         consumeError(ExpectedProgram.takeError());
123406c3fb27SDimitry Andric         return llvm::make_error<CodeViewError>(
123506c3fb27SDimitry Andric             "String table offset outside of bounds of String Table!");
123606c3fb27SDimitry Andric       }
123706c3fb27SDimitry Andric       W.printString("Program", *ExpectedProgram);
123806c3fb27SDimitry Andric     }
123906c3fb27SDimitry Andric     W.printNumber("OffsetInParent", DefRangeSubfield.OffsetInParent);
124006c3fb27SDimitry Andric     printLocalVariableAddrRange(DefRangeSubfield.Range,
124106c3fb27SDimitry Andric                                 DefRangeSubfield.getRelocationOffset());
124206c3fb27SDimitry Andric     printLocalVariableAddrGap(DefRangeSubfield.Gaps);
124306c3fb27SDimitry Andric   });
124406c3fb27SDimitry Andric 
124506c3fb27SDimitry Andric   if (LVSymbol *Symbol = LocalSymbol) {
124606c3fb27SDimitry Andric     Symbol->setHasCodeViewLocation();
124706c3fb27SDimitry Andric     LocalSymbol = nullptr;
124806c3fb27SDimitry Andric 
124906c3fb27SDimitry Andric     // Add location debug location. Operands: [Program, 0].
125006c3fb27SDimitry Andric     dwarf::Attribute Attr = dwarf::Attribute(SymbolKind::S_DEFRANGE_SUBFIELD);
125106c3fb27SDimitry Andric     uint64_t Operand1 = DefRangeSubfield.Program;
125206c3fb27SDimitry Andric 
125306c3fb27SDimitry Andric     LocalVariableAddrRange Range = DefRangeSubfield.Range;
125406c3fb27SDimitry Andric     LVAddress Address =
125506c3fb27SDimitry Andric         Reader->linearAddress(Range.ISectStart, Range.OffsetStart);
125606c3fb27SDimitry Andric 
125706c3fb27SDimitry Andric     Symbol->addLocation(Attr, Address, Address + Range.Range, 0, 0);
125806c3fb27SDimitry Andric     Symbol->addLocationOperands(LVSmall(Attr), {Operand1, /*Operand2=*/0});
125906c3fb27SDimitry Andric   }
126006c3fb27SDimitry Andric 
126106c3fb27SDimitry Andric   return Error::success();
126206c3fb27SDimitry Andric }
126306c3fb27SDimitry Andric 
126406c3fb27SDimitry Andric // S_DEFRANGE
visitKnownRecord(CVSymbol & Record,DefRangeSym & DefRange)126506c3fb27SDimitry Andric Error LVSymbolVisitor::visitKnownRecord(CVSymbol &Record,
126606c3fb27SDimitry Andric                                         DefRangeSym &DefRange) {
126706c3fb27SDimitry Andric   // DefRanges don't have types, just registers and code offsets.
126806c3fb27SDimitry Andric   LLVM_DEBUG({
126906c3fb27SDimitry Andric     if (LocalSymbol)
127006c3fb27SDimitry Andric       W.getOStream() << formatv("Symbol: {0}, ", LocalSymbol->getName());
127106c3fb27SDimitry Andric 
127206c3fb27SDimitry Andric     if (ObjDelegate) {
127306c3fb27SDimitry Andric       DebugStringTableSubsectionRef Strings = ObjDelegate->getStringTable();
127406c3fb27SDimitry Andric       auto ExpectedProgram = Strings.getString(DefRange.Program);
127506c3fb27SDimitry Andric       if (!ExpectedProgram) {
127606c3fb27SDimitry Andric         consumeError(ExpectedProgram.takeError());
127706c3fb27SDimitry Andric         return llvm::make_error<CodeViewError>(
127806c3fb27SDimitry Andric             "String table offset outside of bounds of String Table!");
127906c3fb27SDimitry Andric       }
128006c3fb27SDimitry Andric       W.printString("Program", *ExpectedProgram);
128106c3fb27SDimitry Andric     }
128206c3fb27SDimitry Andric     printLocalVariableAddrRange(DefRange.Range, DefRange.getRelocationOffset());
128306c3fb27SDimitry Andric     printLocalVariableAddrGap(DefRange.Gaps);
128406c3fb27SDimitry Andric   });
128506c3fb27SDimitry Andric 
128606c3fb27SDimitry Andric   if (LVSymbol *Symbol = LocalSymbol) {
128706c3fb27SDimitry Andric     Symbol->setHasCodeViewLocation();
128806c3fb27SDimitry Andric     LocalSymbol = nullptr;
128906c3fb27SDimitry Andric 
129006c3fb27SDimitry Andric     // Add location debug location. Operands: [Program, 0].
129106c3fb27SDimitry Andric     dwarf::Attribute Attr = dwarf::Attribute(SymbolKind::S_DEFRANGE);
129206c3fb27SDimitry Andric     uint64_t Operand1 = DefRange.Program;
129306c3fb27SDimitry Andric 
129406c3fb27SDimitry Andric     LocalVariableAddrRange Range = DefRange.Range;
129506c3fb27SDimitry Andric     LVAddress Address =
129606c3fb27SDimitry Andric         Reader->linearAddress(Range.ISectStart, Range.OffsetStart);
129706c3fb27SDimitry Andric 
129806c3fb27SDimitry Andric     Symbol->addLocation(Attr, Address, Address + Range.Range, 0, 0);
129906c3fb27SDimitry Andric     Symbol->addLocationOperands(LVSmall(Attr), {Operand1, /*Operand2=*/0});
130006c3fb27SDimitry Andric   }
130106c3fb27SDimitry Andric 
130206c3fb27SDimitry Andric   return Error::success();
130306c3fb27SDimitry Andric }
130406c3fb27SDimitry Andric 
130506c3fb27SDimitry Andric // S_FRAMEPROC
visitKnownRecord(CVSymbol & Record,FrameProcSym & FrameProc)130606c3fb27SDimitry Andric Error LVSymbolVisitor::visitKnownRecord(CVSymbol &Record,
130706c3fb27SDimitry Andric                                         FrameProcSym &FrameProc) {
130806c3fb27SDimitry Andric   if (LVScope *Function = LogicalVisitor->getReaderScope()) {
130906c3fb27SDimitry Andric     // S_FRAMEPROC contains extra information for the function described
131006c3fb27SDimitry Andric     // by any of the previous generated records:
131106c3fb27SDimitry Andric     // S_GPROC32, S_LPROC32, S_LPROC32_ID, S_GPROC32_ID.
131206c3fb27SDimitry Andric 
131306c3fb27SDimitry Andric     // The generated sequence is:
131406c3fb27SDimitry Andric     //   S_GPROC32_ID ...
131506c3fb27SDimitry Andric     //   S_FRAMEPROC ...
131606c3fb27SDimitry Andric 
131706c3fb27SDimitry Andric     // Collect additional inline flags for the current scope function.
131806c3fb27SDimitry Andric     FrameProcedureOptions Flags = FrameProc.Flags;
131906c3fb27SDimitry Andric     if (FrameProcedureOptions::MarkedInline ==
132006c3fb27SDimitry Andric         (Flags & FrameProcedureOptions::MarkedInline))
132106c3fb27SDimitry Andric       Function->setInlineCode(dwarf::DW_INL_declared_inlined);
132206c3fb27SDimitry Andric     if (FrameProcedureOptions::Inlined ==
132306c3fb27SDimitry Andric         (Flags & FrameProcedureOptions::Inlined))
132406c3fb27SDimitry Andric       Function->setInlineCode(dwarf::DW_INL_inlined);
132506c3fb27SDimitry Andric 
132606c3fb27SDimitry Andric     // To determine the symbol kind for any symbol declared in that function,
132706c3fb27SDimitry Andric     // we can access the S_FRAMEPROC for the parent scope function. It contains
132806c3fb27SDimitry Andric     // information about the local fp and param fp registers and compare with
132906c3fb27SDimitry Andric     // the register in the S_REGREL32 to get a match.
133006c3fb27SDimitry Andric     codeview::CPUType CPU = Reader->getCompileUnitCPUType();
133106c3fb27SDimitry Andric     LocalFrameRegister = FrameProc.getLocalFramePtrReg(CPU);
133206c3fb27SDimitry Andric     ParamFrameRegister = FrameProc.getParamFramePtrReg(CPU);
133306c3fb27SDimitry Andric   }
133406c3fb27SDimitry Andric 
133506c3fb27SDimitry Andric   return Error::success();
133606c3fb27SDimitry Andric }
133706c3fb27SDimitry Andric 
133806c3fb27SDimitry Andric // S_GDATA32, S_LDATA32, S_LMANDATA, S_GMANDATA
visitKnownRecord(CVSymbol & Record,DataSym & Data)133906c3fb27SDimitry Andric Error LVSymbolVisitor::visitKnownRecord(CVSymbol &Record, DataSym &Data) {
134006c3fb27SDimitry Andric   LLVM_DEBUG({
134106c3fb27SDimitry Andric     printTypeIndex("Type", Data.Type);
134206c3fb27SDimitry Andric     W.printString("DisplayName", Data.Name);
134306c3fb27SDimitry Andric   });
134406c3fb27SDimitry Andric 
134506c3fb27SDimitry Andric   if (LVSymbol *Symbol = LogicalVisitor->CurrentSymbol) {
134606c3fb27SDimitry Andric     StringRef LinkageName;
134706c3fb27SDimitry Andric     if (ObjDelegate)
134806c3fb27SDimitry Andric       ObjDelegate->getLinkageName(Data.getRelocationOffset(), Data.DataOffset,
134906c3fb27SDimitry Andric                                   &LinkageName);
135006c3fb27SDimitry Andric 
135106c3fb27SDimitry Andric     Symbol->setName(Data.Name);
135206c3fb27SDimitry Andric     Symbol->setLinkageName(LinkageName);
135306c3fb27SDimitry Andric 
135406c3fb27SDimitry Andric     // The MSVC generates local data as initialization for aggregates. It
135506c3fb27SDimitry Andric     // contains the address for an initialization function.
135606c3fb27SDimitry Andric     // The symbols contains the '$initializer$' pattern. Allow them only if
135706c3fb27SDimitry Andric     // the '--internal=system' option is given.
135806c3fb27SDimitry Andric     //   0 | S_LDATA32 `Struct$initializer$`
135906c3fb27SDimitry Andric     //       type = 0x1040 (void ()*)
136006c3fb27SDimitry Andric     if (getReader().isSystemEntry(Symbol) && !options().getAttributeSystem()) {
136106c3fb27SDimitry Andric       Symbol->resetIncludeInPrint();
136206c3fb27SDimitry Andric       return Error::success();
136306c3fb27SDimitry Andric     }
136406c3fb27SDimitry Andric 
136506c3fb27SDimitry Andric     if (LVScope *Namespace = Shared->NamespaceDeduction.get(Data.Name)) {
136606c3fb27SDimitry Andric       // The variable is already at different scope. In order to reflect
136706c3fb27SDimitry Andric       // the correct parent, move it to the namespace.
136806c3fb27SDimitry Andric       if (Symbol->getParentScope()->removeElement(Symbol))
136906c3fb27SDimitry Andric         Namespace->addElement(Symbol);
137006c3fb27SDimitry Andric     }
137106c3fb27SDimitry Andric 
137206c3fb27SDimitry Andric     Symbol->setType(LogicalVisitor->getElement(StreamTPI, Data.Type));
137306c3fb27SDimitry Andric     if (Record.kind() == SymbolKind::S_GDATA32)
137406c3fb27SDimitry Andric       Symbol->setIsExternal();
137506c3fb27SDimitry Andric   }
137606c3fb27SDimitry Andric 
137706c3fb27SDimitry Andric   return Error::success();
137806c3fb27SDimitry Andric }
137906c3fb27SDimitry Andric 
138006c3fb27SDimitry Andric // S_INLINESITE
visitKnownRecord(CVSymbol & Record,InlineSiteSym & InlineSite)138106c3fb27SDimitry Andric Error LVSymbolVisitor::visitKnownRecord(CVSymbol &Record,
138206c3fb27SDimitry Andric                                         InlineSiteSym &InlineSite) {
138306c3fb27SDimitry Andric   LLVM_DEBUG({ printTypeIndex("Inlinee", InlineSite.Inlinee); });
138406c3fb27SDimitry Andric 
138506c3fb27SDimitry Andric   if (LVScope *InlinedFunction = LogicalVisitor->CurrentScope) {
138606c3fb27SDimitry Andric     LVScope *AbstractFunction = Reader->createScopeFunction();
138706c3fb27SDimitry Andric     AbstractFunction->setIsSubprogram();
138806c3fb27SDimitry Andric     AbstractFunction->setTag(dwarf::DW_TAG_subprogram);
138906c3fb27SDimitry Andric     AbstractFunction->setInlineCode(dwarf::DW_INL_inlined);
139006c3fb27SDimitry Andric     AbstractFunction->setIsInlinedAbstract();
139106c3fb27SDimitry Andric     InlinedFunction->setReference(AbstractFunction);
139206c3fb27SDimitry Andric 
139306c3fb27SDimitry Andric     LogicalVisitor->startProcessArgumentList();
139406c3fb27SDimitry Andric     // 'Inlinee' is a Type ID.
139506c3fb27SDimitry Andric     CVType CVFunctionType = Ids.getType(InlineSite.Inlinee);
139606c3fb27SDimitry Andric     if (Error Err = LogicalVisitor->finishVisitation(
139706c3fb27SDimitry Andric             CVFunctionType, InlineSite.Inlinee, AbstractFunction))
139806c3fb27SDimitry Andric       return Err;
139906c3fb27SDimitry Andric     LogicalVisitor->stopProcessArgumentList();
140006c3fb27SDimitry Andric 
140106c3fb27SDimitry Andric     // For inlined functions set the linkage name to be the same as
140206c3fb27SDimitry Andric     // the name. It used to find their lines and ranges.
140306c3fb27SDimitry Andric     StringRef Name = AbstractFunction->getName();
140406c3fb27SDimitry Andric     InlinedFunction->setName(Name);
140506c3fb27SDimitry Andric     InlinedFunction->setLinkageName(Name);
140606c3fb27SDimitry Andric 
140706c3fb27SDimitry Andric     // Process annotation bytes to calculate code and line offsets.
140806c3fb27SDimitry Andric     if (Error Err = LogicalVisitor->inlineSiteAnnotation(
140906c3fb27SDimitry Andric             AbstractFunction, InlinedFunction, InlineSite))
141006c3fb27SDimitry Andric       return Err;
141106c3fb27SDimitry Andric   }
141206c3fb27SDimitry Andric 
141306c3fb27SDimitry Andric   return Error::success();
141406c3fb27SDimitry Andric }
141506c3fb27SDimitry Andric 
141606c3fb27SDimitry Andric // S_LOCAL
visitKnownRecord(CVSymbol & Record,LocalSym & Local)141706c3fb27SDimitry Andric Error LVSymbolVisitor::visitKnownRecord(CVSymbol &Record, LocalSym &Local) {
141806c3fb27SDimitry Andric   LLVM_DEBUG({
141906c3fb27SDimitry Andric     printTypeIndex("Type", Local.Type);
142006c3fb27SDimitry Andric     W.printFlags("Flags", uint16_t(Local.Flags), getLocalFlagNames());
142106c3fb27SDimitry Andric     W.printString("VarName", Local.Name);
142206c3fb27SDimitry Andric   });
142306c3fb27SDimitry Andric 
142406c3fb27SDimitry Andric   if (LVSymbol *Symbol = LogicalVisitor->CurrentSymbol) {
142506c3fb27SDimitry Andric     Symbol->setName(Local.Name);
142606c3fb27SDimitry Andric 
142706c3fb27SDimitry Andric     // Symbol was created as 'variable'; determine its real kind.
142806c3fb27SDimitry Andric     Symbol->resetIsVariable();
142906c3fb27SDimitry Andric 
143006c3fb27SDimitry Andric     // Be sure the 'this' symbol is marked as 'compiler generated'.
143106c3fb27SDimitry Andric     if (bool(Local.Flags & LocalSymFlags::IsCompilerGenerated) ||
143206c3fb27SDimitry Andric         Local.Name.equals("this")) {
143306c3fb27SDimitry Andric       Symbol->setIsArtificial();
143406c3fb27SDimitry Andric       Symbol->setIsParameter();
143506c3fb27SDimitry Andric     } else {
143606c3fb27SDimitry Andric       bool(Local.Flags & LocalSymFlags::IsParameter) ? Symbol->setIsParameter()
143706c3fb27SDimitry Andric                                                      : Symbol->setIsVariable();
143806c3fb27SDimitry Andric     }
143906c3fb27SDimitry Andric 
144006c3fb27SDimitry Andric     // Update correct debug information tag.
144106c3fb27SDimitry Andric     if (Symbol->getIsParameter())
144206c3fb27SDimitry Andric       Symbol->setTag(dwarf::DW_TAG_formal_parameter);
144306c3fb27SDimitry Andric 
144406c3fb27SDimitry Andric     LVElement *Element = LogicalVisitor->getElement(StreamTPI, Local.Type);
144506c3fb27SDimitry Andric     if (Element && Element->getIsScoped()) {
144606c3fb27SDimitry Andric       // We have a local type. Find its parent function.
144706c3fb27SDimitry Andric       LVScope *Parent = Symbol->getFunctionParent();
144806c3fb27SDimitry Andric       // The element representing the type has been already finalized. If
144906c3fb27SDimitry Andric       // the type is an aggregate type, its members have been already added.
145006c3fb27SDimitry Andric       // As the type is local, its level will be changed.
145106c3fb27SDimitry Andric       Parent->addElement(Element);
145206c3fb27SDimitry Andric       Element->updateLevel(Parent);
145306c3fb27SDimitry Andric     }
145406c3fb27SDimitry Andric     Symbol->setType(Element);
145506c3fb27SDimitry Andric 
145606c3fb27SDimitry Andric     // The CodeView records (S_DEFFRAME_*) describing debug location for
145706c3fb27SDimitry Andric     // this symbol, do not have any direct reference to it. Those records
145806c3fb27SDimitry Andric     // are emitted after this symbol. Record the current symbol.
145906c3fb27SDimitry Andric     LocalSymbol = Symbol;
146006c3fb27SDimitry Andric   }
146106c3fb27SDimitry Andric 
146206c3fb27SDimitry Andric   return Error::success();
146306c3fb27SDimitry Andric }
146406c3fb27SDimitry Andric 
146506c3fb27SDimitry Andric // S_OBJNAME
visitKnownRecord(CVSymbol & Record,ObjNameSym & ObjName)146606c3fb27SDimitry Andric Error LVSymbolVisitor::visitKnownRecord(CVSymbol &Record, ObjNameSym &ObjName) {
146706c3fb27SDimitry Andric   LLVM_DEBUG({
146806c3fb27SDimitry Andric     W.printHex("Signature", ObjName.Signature);
146906c3fb27SDimitry Andric     W.printString("ObjectName", ObjName.Name);
147006c3fb27SDimitry Andric   });
147106c3fb27SDimitry Andric 
147206c3fb27SDimitry Andric   CurrentObjectName = ObjName.Name;
147306c3fb27SDimitry Andric   return Error::success();
147406c3fb27SDimitry Andric }
147506c3fb27SDimitry Andric 
147606c3fb27SDimitry Andric // S_GPROC32, S_LPROC32, S_LPROC32_ID, S_GPROC32_ID
visitKnownRecord(CVSymbol & Record,ProcSym & Proc)147706c3fb27SDimitry Andric Error LVSymbolVisitor::visitKnownRecord(CVSymbol &Record, ProcSym &Proc) {
147806c3fb27SDimitry Andric   if (InFunctionScope)
147906c3fb27SDimitry Andric     return llvm::make_error<CodeViewError>("Visiting a ProcSym while inside "
148006c3fb27SDimitry Andric                                            "function scope!");
148106c3fb27SDimitry Andric 
148206c3fb27SDimitry Andric   InFunctionScope = true;
148306c3fb27SDimitry Andric 
148406c3fb27SDimitry Andric   LLVM_DEBUG({
148506c3fb27SDimitry Andric     printTypeIndex("FunctionType", Proc.FunctionType);
148606c3fb27SDimitry Andric     W.printHex("Segment", Proc.Segment);
148706c3fb27SDimitry Andric     W.printFlags("Flags", static_cast<uint8_t>(Proc.Flags),
148806c3fb27SDimitry Andric                  getProcSymFlagNames());
148906c3fb27SDimitry Andric     W.printString("DisplayName", Proc.Name);
149006c3fb27SDimitry Andric   });
149106c3fb27SDimitry Andric 
149206c3fb27SDimitry Andric   // Clang and Microsoft generated different debug information records:
149306c3fb27SDimitry Andric   // For functions definitions:
149406c3fb27SDimitry Andric   // Clang:     S_GPROC32 -> LF_FUNC_ID -> LF_PROCEDURE
149506c3fb27SDimitry Andric   // Microsoft: S_GPROC32 ->               LF_PROCEDURE
149606c3fb27SDimitry Andric 
149706c3fb27SDimitry Andric   // For member function definition:
149806c3fb27SDimitry Andric   // Clang:     S_GPROC32 -> LF_MFUNC_ID -> LF_MFUNCTION
149906c3fb27SDimitry Andric   // Microsoft: S_GPROC32 ->                LF_MFUNCTION
150006c3fb27SDimitry Andric   // In order to support both sequences, if we found LF_FUNCTION_ID, just
150106c3fb27SDimitry Andric   // get the TypeIndex for LF_PROCEDURE.
150206c3fb27SDimitry Andric 
150306c3fb27SDimitry Andric   // For the given test case, we have the sequence:
150406c3fb27SDimitry Andric   // namespace NSP_local {
150506c3fb27SDimitry Andric   //   void foo_local() {
150606c3fb27SDimitry Andric   //   }
150706c3fb27SDimitry Andric   // }
150806c3fb27SDimitry Andric   //
150906c3fb27SDimitry Andric   // 0x1000 | LF_STRING_ID String: NSP_local
151006c3fb27SDimitry Andric   // 0x1002 | LF_PROCEDURE
151106c3fb27SDimitry Andric   //          return type = 0x0003 (void), # args = 0, param list = 0x1001
151206c3fb27SDimitry Andric   //          calling conv = cdecl, options = None
151306c3fb27SDimitry Andric   // 0x1003 | LF_FUNC_ID
151406c3fb27SDimitry Andric   //          name = foo_local, type = 0x1002, parent scope = 0x1000
151506c3fb27SDimitry Andric   //      0 | S_GPROC32_ID `NSP_local::foo_local`
151606c3fb27SDimitry Andric   //          type = `0x1003 (foo_local)`
151706c3fb27SDimitry Andric   // 0x1004 | LF_STRING_ID String: suite
151806c3fb27SDimitry Andric   // 0x1005 | LF_STRING_ID String: suite_local.cpp
151906c3fb27SDimitry Andric   //
152006c3fb27SDimitry Andric   // The LF_STRING_ID can hold different information:
152106c3fb27SDimitry Andric   // 0x1000 - The enclosing namespace.
152206c3fb27SDimitry Andric   // 0x1004 - The compile unit directory name.
152306c3fb27SDimitry Andric   // 0x1005 - The compile unit name.
152406c3fb27SDimitry Andric   //
152506c3fb27SDimitry Andric   // Before deducting its scope, we need to evaluate its type and create any
152606c3fb27SDimitry Andric   // associated namespaces.
152706c3fb27SDimitry Andric   if (LVScope *Function = LogicalVisitor->CurrentScope) {
152806c3fb27SDimitry Andric     StringRef LinkageName;
152906c3fb27SDimitry Andric     if (ObjDelegate)
153006c3fb27SDimitry Andric       ObjDelegate->getLinkageName(Proc.getRelocationOffset(), Proc.CodeOffset,
153106c3fb27SDimitry Andric                                   &LinkageName);
153206c3fb27SDimitry Andric 
153306c3fb27SDimitry Andric     // The line table can be accessed using the linkage name.
153406c3fb27SDimitry Andric     Reader->addToSymbolTable(LinkageName, Function);
153506c3fb27SDimitry Andric     Function->setName(Proc.Name);
153606c3fb27SDimitry Andric     Function->setLinkageName(LinkageName);
153706c3fb27SDimitry Andric 
153806c3fb27SDimitry Andric     if (options().getGeneralCollectRanges()) {
153906c3fb27SDimitry Andric       // Record converted segment::offset addressing for this scope.
154006c3fb27SDimitry Andric       LVAddress Addendum = Reader->getSymbolTableAddress(LinkageName);
154106c3fb27SDimitry Andric       LVAddress LowPC =
154206c3fb27SDimitry Andric           Reader->linearAddress(Proc.Segment, Proc.CodeOffset, Addendum);
154306c3fb27SDimitry Andric       LVAddress HighPC = LowPC + Proc.CodeSize - 1;
154406c3fb27SDimitry Andric       Function->addObject(LowPC, HighPC);
154506c3fb27SDimitry Andric 
154606c3fb27SDimitry Andric       // If the scope is a function, add it to the public names.
154706c3fb27SDimitry Andric       if ((options().getAttributePublics() || options().getPrintAnyLine()) &&
154806c3fb27SDimitry Andric           !Function->getIsInlinedFunction())
154906c3fb27SDimitry Andric         Reader->getCompileUnit()->addPublicName(Function, LowPC, HighPC);
155006c3fb27SDimitry Andric     }
155106c3fb27SDimitry Andric 
155206c3fb27SDimitry Andric     if (Function->getIsSystem() && !options().getAttributeSystem()) {
155306c3fb27SDimitry Andric       Function->resetIncludeInPrint();
155406c3fb27SDimitry Andric       return Error::success();
155506c3fb27SDimitry Andric     }
155606c3fb27SDimitry Andric 
155706c3fb27SDimitry Andric     TypeIndex TIFunctionType = Proc.FunctionType;
155806c3fb27SDimitry Andric     if (TIFunctionType.isSimple())
155906c3fb27SDimitry Andric       Function->setType(LogicalVisitor->getElement(StreamTPI, TIFunctionType));
156006c3fb27SDimitry Andric     else {
156106c3fb27SDimitry Andric       // We have to detect the correct stream, using the lexical parent
156206c3fb27SDimitry Andric       // name, as there is not other obvious way to get the stream.
156306c3fb27SDimitry Andric       //   Normal function: LF_FUNC_ID (TPI)/(IPI)
156406c3fb27SDimitry Andric       //                    LF_PROCEDURE (TPI)
156506c3fb27SDimitry Andric       //   Lambda function: LF_MFUNCTION (TPI)
156606c3fb27SDimitry Andric       //   Member function: LF_MFUNC_ID (TPI)/(IPI)
156706c3fb27SDimitry Andric 
156806c3fb27SDimitry Andric       StringRef OuterComponent;
156906c3fb27SDimitry Andric       std::tie(OuterComponent, std::ignore) = getInnerComponent(Proc.Name);
157006c3fb27SDimitry Andric       TypeIndex TI = Shared->ForwardReferences.find(OuterComponent);
157106c3fb27SDimitry Andric 
157206c3fb27SDimitry Andric       std::optional<CVType> CVFunctionType;
157306c3fb27SDimitry Andric       auto GetRecordType = [&]() -> bool {
157406c3fb27SDimitry Andric         CVFunctionType = Ids.tryGetType(TIFunctionType);
157506c3fb27SDimitry Andric         if (!CVFunctionType)
157606c3fb27SDimitry Andric           return false;
157706c3fb27SDimitry Andric 
157806c3fb27SDimitry Andric         if (TI.isNoneType())
157906c3fb27SDimitry Andric           // Normal function.
158006c3fb27SDimitry Andric           if (CVFunctionType->kind() == LF_FUNC_ID)
158106c3fb27SDimitry Andric             return true;
158206c3fb27SDimitry Andric 
158306c3fb27SDimitry Andric         // Member function.
158406c3fb27SDimitry Andric         return (CVFunctionType->kind() == LF_MFUNC_ID);
158506c3fb27SDimitry Andric       };
158606c3fb27SDimitry Andric 
158706c3fb27SDimitry Andric       // We can have a LF_FUNC_ID, LF_PROCEDURE or LF_MFUNCTION.
158806c3fb27SDimitry Andric       if (!GetRecordType()) {
158906c3fb27SDimitry Andric         CVFunctionType = Types.tryGetType(TIFunctionType);
159006c3fb27SDimitry Andric         if (!CVFunctionType)
159106c3fb27SDimitry Andric           return llvm::make_error<CodeViewError>("Invalid type index");
159206c3fb27SDimitry Andric       }
159306c3fb27SDimitry Andric 
159406c3fb27SDimitry Andric       if (Error Err = LogicalVisitor->finishVisitation(
159506c3fb27SDimitry Andric               *CVFunctionType, TIFunctionType, Function))
159606c3fb27SDimitry Andric         return Err;
159706c3fb27SDimitry Andric     }
159806c3fb27SDimitry Andric 
159906c3fb27SDimitry Andric     if (Record.kind() == SymbolKind::S_GPROC32 ||
160006c3fb27SDimitry Andric         Record.kind() == SymbolKind::S_GPROC32_ID)
160106c3fb27SDimitry Andric       Function->setIsExternal();
160206c3fb27SDimitry Andric 
160306c3fb27SDimitry Andric     // We don't have a way to see if the symbol is compiler generated. Use
160406c3fb27SDimitry Andric     // the linkage name, to detect `scalar deleting destructor' functions.
160506c3fb27SDimitry Andric     std::string DemangledSymbol = demangle(LinkageName);
160606c3fb27SDimitry Andric     if (DemangledSymbol.find("scalar deleting dtor") != std::string::npos) {
160706c3fb27SDimitry Andric       Function->setIsArtificial();
160806c3fb27SDimitry Andric     } else {
160906c3fb27SDimitry Andric       // Clang generates global ctor and dtor names containing the substrings:
161006c3fb27SDimitry Andric       // 'dynamic initializer for' and 'dynamic atexit destructor for'.
161106c3fb27SDimitry Andric       if (DemangledSymbol.find("dynamic atexit destructor for") !=
161206c3fb27SDimitry Andric           std::string::npos)
161306c3fb27SDimitry Andric         Function->setIsArtificial();
161406c3fb27SDimitry Andric     }
161506c3fb27SDimitry Andric   }
161606c3fb27SDimitry Andric 
161706c3fb27SDimitry Andric   return Error::success();
161806c3fb27SDimitry Andric }
161906c3fb27SDimitry Andric 
162006c3fb27SDimitry Andric // S_END
visitKnownRecord(CVSymbol & Record,ScopeEndSym & ScopeEnd)162106c3fb27SDimitry Andric Error LVSymbolVisitor::visitKnownRecord(CVSymbol &Record,
162206c3fb27SDimitry Andric                                         ScopeEndSym &ScopeEnd) {
162306c3fb27SDimitry Andric   InFunctionScope = false;
162406c3fb27SDimitry Andric   return Error::success();
162506c3fb27SDimitry Andric }
162606c3fb27SDimitry Andric 
162706c3fb27SDimitry Andric // S_THUNK32
visitKnownRecord(CVSymbol & Record,Thunk32Sym & Thunk)162806c3fb27SDimitry Andric Error LVSymbolVisitor::visitKnownRecord(CVSymbol &Record, Thunk32Sym &Thunk) {
162906c3fb27SDimitry Andric   if (InFunctionScope)
163006c3fb27SDimitry Andric     return llvm::make_error<CodeViewError>("Visiting a Thunk32Sym while inside "
163106c3fb27SDimitry Andric                                            "function scope!");
163206c3fb27SDimitry Andric 
163306c3fb27SDimitry Andric   InFunctionScope = true;
163406c3fb27SDimitry Andric 
163506c3fb27SDimitry Andric   LLVM_DEBUG({
163606c3fb27SDimitry Andric     W.printHex("Segment", Thunk.Segment);
163706c3fb27SDimitry Andric     W.printString("Name", Thunk.Name);
163806c3fb27SDimitry Andric   });
163906c3fb27SDimitry Andric 
164006c3fb27SDimitry Andric   if (LVScope *Function = LogicalVisitor->CurrentScope)
164106c3fb27SDimitry Andric     Function->setName(Thunk.Name);
164206c3fb27SDimitry Andric 
164306c3fb27SDimitry Andric   return Error::success();
164406c3fb27SDimitry Andric }
164506c3fb27SDimitry Andric 
164606c3fb27SDimitry Andric // S_UDT, S_COBOLUDT
visitKnownRecord(CVSymbol & Record,UDTSym & UDT)164706c3fb27SDimitry Andric Error LVSymbolVisitor::visitKnownRecord(CVSymbol &Record, UDTSym &UDT) {
164806c3fb27SDimitry Andric   LLVM_DEBUG({
164906c3fb27SDimitry Andric     printTypeIndex("Type", UDT.Type);
165006c3fb27SDimitry Andric     W.printString("UDTName", UDT.Name);
165106c3fb27SDimitry Andric   });
165206c3fb27SDimitry Andric 
165306c3fb27SDimitry Andric   if (LVType *Type = LogicalVisitor->CurrentType) {
165406c3fb27SDimitry Andric     if (LVScope *Namespace = Shared->NamespaceDeduction.get(UDT.Name)) {
165506c3fb27SDimitry Andric       if (Type->getParentScope()->removeElement(Type))
165606c3fb27SDimitry Andric         Namespace->addElement(Type);
165706c3fb27SDimitry Andric     }
165806c3fb27SDimitry Andric 
165906c3fb27SDimitry Andric     Type->setName(UDT.Name);
166006c3fb27SDimitry Andric 
166106c3fb27SDimitry Andric     // We have to determine if the typedef is a real C/C++ definition or is
166206c3fb27SDimitry Andric     // the S_UDT record that describe all the user defined types.
166306c3fb27SDimitry Andric     //      0 | S_UDT `Name` original type = 0x1009
166406c3fb27SDimitry Andric     // 0x1009 | LF_STRUCTURE `Name`
166506c3fb27SDimitry Andric     // Ignore type definitions for RTTI types:
166606c3fb27SDimitry Andric     // _s__RTTIBaseClassArray, _s__RTTIBaseClassDescriptor,
166706c3fb27SDimitry Andric     // _s__RTTICompleteObjectLocator, _s__RTTIClassHierarchyDescriptor.
166806c3fb27SDimitry Andric     if (getReader().isSystemEntry(Type))
166906c3fb27SDimitry Andric       Type->resetIncludeInPrint();
167006c3fb27SDimitry Andric     else {
167106c3fb27SDimitry Andric       StringRef RecordName = getRecordName(Types, UDT.Type);
167206c3fb27SDimitry Andric       if (UDT.Name.equals(RecordName))
167306c3fb27SDimitry Andric         Type->resetIncludeInPrint();
167406c3fb27SDimitry Andric       Type->setType(LogicalVisitor->getElement(StreamTPI, UDT.Type));
167506c3fb27SDimitry Andric     }
167606c3fb27SDimitry Andric   }
167706c3fb27SDimitry Andric 
167806c3fb27SDimitry Andric   return Error::success();
167906c3fb27SDimitry Andric }
168006c3fb27SDimitry Andric 
168106c3fb27SDimitry Andric // S_UNAMESPACE
visitKnownRecord(CVSymbol & Record,UsingNamespaceSym & UN)168206c3fb27SDimitry Andric Error LVSymbolVisitor::visitKnownRecord(CVSymbol &Record,
168306c3fb27SDimitry Andric                                         UsingNamespaceSym &UN) {
168406c3fb27SDimitry Andric   LLVM_DEBUG({ W.printString("Namespace", UN.Name); });
168506c3fb27SDimitry Andric   return Error::success();
168606c3fb27SDimitry Andric }
168706c3fb27SDimitry Andric 
1688*5f757f3fSDimitry Andric // S_ARMSWITCHTABLE
visitKnownRecord(CVSymbol & CVR,JumpTableSym & JumpTable)1689*5f757f3fSDimitry Andric Error LVSymbolVisitor::visitKnownRecord(CVSymbol &CVR,
1690*5f757f3fSDimitry Andric                                         JumpTableSym &JumpTable) {
1691*5f757f3fSDimitry Andric   LLVM_DEBUG({
1692*5f757f3fSDimitry Andric     W.printHex("BaseOffset", JumpTable.BaseOffset);
1693*5f757f3fSDimitry Andric     W.printNumber("BaseSegment", JumpTable.BaseSegment);
1694*5f757f3fSDimitry Andric     W.printFlags("SwitchType", static_cast<uint16_t>(JumpTable.SwitchType),
1695*5f757f3fSDimitry Andric                  getJumpTableEntrySizeNames());
1696*5f757f3fSDimitry Andric     W.printHex("BranchOffset", JumpTable.BranchOffset);
1697*5f757f3fSDimitry Andric     W.printHex("TableOffset", JumpTable.TableOffset);
1698*5f757f3fSDimitry Andric     W.printNumber("BranchSegment", JumpTable.BranchSegment);
1699*5f757f3fSDimitry Andric     W.printNumber("TableSegment", JumpTable.TableSegment);
1700*5f757f3fSDimitry Andric     W.printNumber("EntriesCount", JumpTable.EntriesCount);
1701*5f757f3fSDimitry Andric   });
1702*5f757f3fSDimitry Andric   return Error::success();
1703*5f757f3fSDimitry Andric }
1704*5f757f3fSDimitry Andric 
1705*5f757f3fSDimitry Andric // S_CALLERS, S_CALLEES, S_INLINEES
visitKnownRecord(CVSymbol & Record,CallerSym & Caller)1706*5f757f3fSDimitry Andric Error LVSymbolVisitor::visitKnownRecord(CVSymbol &Record, CallerSym &Caller) {
1707*5f757f3fSDimitry Andric   LLVM_DEBUG({
1708*5f757f3fSDimitry Andric     llvm::StringRef FieldName;
1709*5f757f3fSDimitry Andric     switch (Caller.getKind()) {
1710*5f757f3fSDimitry Andric     case SymbolRecordKind::CallerSym:
1711*5f757f3fSDimitry Andric       FieldName = "Callee";
1712*5f757f3fSDimitry Andric       break;
1713*5f757f3fSDimitry Andric     case SymbolRecordKind::CalleeSym:
1714*5f757f3fSDimitry Andric       FieldName = "Caller";
1715*5f757f3fSDimitry Andric       break;
1716*5f757f3fSDimitry Andric     case SymbolRecordKind::InlineesSym:
1717*5f757f3fSDimitry Andric       FieldName = "Inlinee";
1718*5f757f3fSDimitry Andric       break;
1719*5f757f3fSDimitry Andric     default:
1720*5f757f3fSDimitry Andric       return llvm::make_error<CodeViewError>(
1721*5f757f3fSDimitry Andric           "Unknown CV Record type for a CallerSym object!");
1722*5f757f3fSDimitry Andric     }
1723*5f757f3fSDimitry Andric     for (auto FuncID : Caller.Indices) {
1724*5f757f3fSDimitry Andric       printTypeIndex(FieldName, FuncID);
1725*5f757f3fSDimitry Andric     }
1726*5f757f3fSDimitry Andric   });
1727*5f757f3fSDimitry Andric   return Error::success();
1728*5f757f3fSDimitry Andric }
1729*5f757f3fSDimitry Andric 
173006c3fb27SDimitry Andric #undef DEBUG_TYPE
173106c3fb27SDimitry Andric #define DEBUG_TYPE "CodeViewLogicalVisitor"
173206c3fb27SDimitry Andric 
173306c3fb27SDimitry Andric //===----------------------------------------------------------------------===//
173406c3fb27SDimitry Andric // Logical visitor.
173506c3fb27SDimitry Andric //===----------------------------------------------------------------------===//
LVLogicalVisitor(LVCodeViewReader * Reader,ScopedPrinter & W,InputFile & Input)173606c3fb27SDimitry Andric LVLogicalVisitor::LVLogicalVisitor(LVCodeViewReader *Reader, ScopedPrinter &W,
173706c3fb27SDimitry Andric                                    InputFile &Input)
173806c3fb27SDimitry Andric     : Reader(Reader), W(W), Input(Input) {
173906c3fb27SDimitry Andric   // The LogicalVisitor connects the CodeViewReader with the visitors that
174006c3fb27SDimitry Andric   // traverse the types, symbols, etc. Do any initialization that is needed.
174106c3fb27SDimitry Andric   Shared = std::make_shared<LVShared>(Reader, this);
174206c3fb27SDimitry Andric }
174306c3fb27SDimitry Andric 
printTypeIndex(StringRef FieldName,TypeIndex TI,uint32_t StreamIdx)174406c3fb27SDimitry Andric void LVLogicalVisitor::printTypeIndex(StringRef FieldName, TypeIndex TI,
174506c3fb27SDimitry Andric                                       uint32_t StreamIdx) {
174606c3fb27SDimitry Andric   codeview::printTypeIndex(W, FieldName, TI,
174706c3fb27SDimitry Andric                            StreamIdx == StreamTPI ? types() : ids());
174806c3fb27SDimitry Andric }
174906c3fb27SDimitry Andric 
printTypeBegin(CVType & Record,TypeIndex TI,LVElement * Element,uint32_t StreamIdx)175006c3fb27SDimitry Andric void LVLogicalVisitor::printTypeBegin(CVType &Record, TypeIndex TI,
175106c3fb27SDimitry Andric                                       LVElement *Element, uint32_t StreamIdx) {
175206c3fb27SDimitry Andric   W.getOStream() << "\n";
175306c3fb27SDimitry Andric   W.startLine() << formatTypeLeafKind(Record.kind());
175406c3fb27SDimitry Andric   W.getOStream() << " (" << HexNumber(TI.getIndex()) << ")";
175506c3fb27SDimitry Andric   W.getOStream() << " {\n";
175606c3fb27SDimitry Andric   W.indent();
175706c3fb27SDimitry Andric   W.printEnum("TypeLeafKind", unsigned(Record.kind()), ArrayRef(LeafTypeNames));
175806c3fb27SDimitry Andric   printTypeIndex("TI", TI, StreamIdx);
175906c3fb27SDimitry Andric   W.startLine() << "Element: " << HexNumber(Element->getOffset()) << " "
176006c3fb27SDimitry Andric                 << Element->getName() << "\n";
176106c3fb27SDimitry Andric }
176206c3fb27SDimitry Andric 
printTypeEnd(CVType & Record)176306c3fb27SDimitry Andric void LVLogicalVisitor::printTypeEnd(CVType &Record) {
176406c3fb27SDimitry Andric   W.unindent();
176506c3fb27SDimitry Andric   W.startLine() << "}\n";
176606c3fb27SDimitry Andric }
176706c3fb27SDimitry Andric 
printMemberBegin(CVMemberRecord & Record,TypeIndex TI,LVElement * Element,uint32_t StreamIdx)176806c3fb27SDimitry Andric void LVLogicalVisitor::printMemberBegin(CVMemberRecord &Record, TypeIndex TI,
176906c3fb27SDimitry Andric                                         LVElement *Element,
177006c3fb27SDimitry Andric                                         uint32_t StreamIdx) {
177106c3fb27SDimitry Andric   W.getOStream() << "\n";
177206c3fb27SDimitry Andric   W.startLine() << formatTypeLeafKind(Record.Kind);
177306c3fb27SDimitry Andric   W.getOStream() << " (" << HexNumber(TI.getIndex()) << ")";
177406c3fb27SDimitry Andric   W.getOStream() << " {\n";
177506c3fb27SDimitry Andric   W.indent();
177606c3fb27SDimitry Andric   W.printEnum("TypeLeafKind", unsigned(Record.Kind), ArrayRef(LeafTypeNames));
177706c3fb27SDimitry Andric   printTypeIndex("TI", TI, StreamIdx);
177806c3fb27SDimitry Andric   W.startLine() << "Element: " << HexNumber(Element->getOffset()) << " "
177906c3fb27SDimitry Andric                 << Element->getName() << "\n";
178006c3fb27SDimitry Andric }
178106c3fb27SDimitry Andric 
printMemberEnd(CVMemberRecord & Record)178206c3fb27SDimitry Andric void LVLogicalVisitor::printMemberEnd(CVMemberRecord &Record) {
178306c3fb27SDimitry Andric   W.unindent();
178406c3fb27SDimitry Andric   W.startLine() << "}\n";
178506c3fb27SDimitry Andric }
178606c3fb27SDimitry Andric 
visitUnknownType(CVType & Record,TypeIndex TI)178706c3fb27SDimitry Andric Error LVLogicalVisitor::visitUnknownType(CVType &Record, TypeIndex TI) {
178806c3fb27SDimitry Andric   LLVM_DEBUG({
178906c3fb27SDimitry Andric     printTypeIndex("\nTI", TI, StreamTPI);
179006c3fb27SDimitry Andric     W.printNumber("Length", uint32_t(Record.content().size()));
179106c3fb27SDimitry Andric   });
179206c3fb27SDimitry Andric   return Error::success();
179306c3fb27SDimitry Andric }
179406c3fb27SDimitry Andric 
179506c3fb27SDimitry Andric // LF_ARGLIST (TPI)
visitKnownRecord(CVType & Record,ArgListRecord & Args,TypeIndex TI,LVElement * Element)179606c3fb27SDimitry Andric Error LVLogicalVisitor::visitKnownRecord(CVType &Record, ArgListRecord &Args,
179706c3fb27SDimitry Andric                                          TypeIndex TI, LVElement *Element) {
179806c3fb27SDimitry Andric   ArrayRef<TypeIndex> Indices = Args.getIndices();
179906c3fb27SDimitry Andric   uint32_t Size = Indices.size();
180006c3fb27SDimitry Andric   LLVM_DEBUG({
180106c3fb27SDimitry Andric     printTypeBegin(Record, TI, Element, StreamTPI);
180206c3fb27SDimitry Andric     W.printNumber("NumArgs", Size);
180306c3fb27SDimitry Andric     ListScope Arguments(W, "Arguments");
180406c3fb27SDimitry Andric     for (uint32_t I = 0; I < Size; ++I)
180506c3fb27SDimitry Andric       printTypeIndex("ArgType", Indices[I], StreamTPI);
180606c3fb27SDimitry Andric     printTypeEnd(Record);
180706c3fb27SDimitry Andric   });
180806c3fb27SDimitry Andric 
180906c3fb27SDimitry Andric   LVScope *Function = static_cast<LVScope *>(Element);
181006c3fb27SDimitry Andric   for (uint32_t Index = 0; Index < Size; ++Index) {
181106c3fb27SDimitry Andric     TypeIndex ParameterType = Indices[Index];
181206c3fb27SDimitry Andric     createParameter(ParameterType, StringRef(), Function);
181306c3fb27SDimitry Andric   }
181406c3fb27SDimitry Andric 
181506c3fb27SDimitry Andric   return Error::success();
181606c3fb27SDimitry Andric }
181706c3fb27SDimitry Andric 
181806c3fb27SDimitry Andric // LF_ARRAY (TPI)
visitKnownRecord(CVType & Record,ArrayRecord & AT,TypeIndex TI,LVElement * Element)181906c3fb27SDimitry Andric Error LVLogicalVisitor::visitKnownRecord(CVType &Record, ArrayRecord &AT,
182006c3fb27SDimitry Andric                                          TypeIndex TI, LVElement *Element) {
182106c3fb27SDimitry Andric   LLVM_DEBUG({
182206c3fb27SDimitry Andric     printTypeBegin(Record, TI, Element, StreamTPI);
182306c3fb27SDimitry Andric     printTypeIndex("ElementType", AT.getElementType(), StreamTPI);
182406c3fb27SDimitry Andric     printTypeIndex("IndexType", AT.getIndexType(), StreamTPI);
182506c3fb27SDimitry Andric     W.printNumber("SizeOf", AT.getSize());
182606c3fb27SDimitry Andric     W.printString("Name", AT.getName());
182706c3fb27SDimitry Andric     printTypeEnd(Record);
182806c3fb27SDimitry Andric   });
182906c3fb27SDimitry Andric 
183006c3fb27SDimitry Andric   if (Element->getIsFinalized())
183106c3fb27SDimitry Andric     return Error::success();
183206c3fb27SDimitry Andric   Element->setIsFinalized();
183306c3fb27SDimitry Andric 
183406c3fb27SDimitry Andric   LVScopeArray *Array = static_cast<LVScopeArray *>(Element);
183506c3fb27SDimitry Andric   if (!Array)
183606c3fb27SDimitry Andric     return Error::success();
183706c3fb27SDimitry Andric 
183806c3fb27SDimitry Andric   Reader->getCompileUnit()->addElement(Array);
183906c3fb27SDimitry Andric   TypeIndex TIElementType = AT.getElementType();
184006c3fb27SDimitry Andric 
184106c3fb27SDimitry Andric   LVType *PrevSubrange = nullptr;
184206c3fb27SDimitry Andric   LazyRandomTypeCollection &Types = types();
184306c3fb27SDimitry Andric 
184406c3fb27SDimitry Andric   // As the logical view is modeled on DWARF, for each dimension we have to
184506c3fb27SDimitry Andric   // create a DW_TAG_subrange_type, with dimension size.
184606c3fb27SDimitry Andric   // The subrange type can be: unsigned __int32 or unsigned __int64.
184706c3fb27SDimitry Andric   auto AddSubrangeType = [&](ArrayRecord &AR) {
184806c3fb27SDimitry Andric     LVType *Subrange = Reader->createTypeSubrange();
184906c3fb27SDimitry Andric     Subrange->setTag(dwarf::DW_TAG_subrange_type);
185006c3fb27SDimitry Andric     Subrange->setType(getElement(StreamTPI, AR.getIndexType()));
185106c3fb27SDimitry Andric     Subrange->setCount(AR.getSize());
185206c3fb27SDimitry Andric     Subrange->setOffset(
185306c3fb27SDimitry Andric         TIElementType.isSimple()
185406c3fb27SDimitry Andric             ? (uint32_t)(TypeLeafKind)TIElementType.getSimpleKind()
185506c3fb27SDimitry Andric             : TIElementType.getIndex());
185606c3fb27SDimitry Andric     Array->addElement(Subrange);
185706c3fb27SDimitry Andric 
185806c3fb27SDimitry Andric     if (PrevSubrange)
185906c3fb27SDimitry Andric       if (int64_t Count = Subrange->getCount())
186006c3fb27SDimitry Andric         PrevSubrange->setCount(PrevSubrange->getCount() / Count);
186106c3fb27SDimitry Andric     PrevSubrange = Subrange;
186206c3fb27SDimitry Andric   };
186306c3fb27SDimitry Andric 
186406c3fb27SDimitry Andric   // Preserve the original TypeIndex; it would be updated in the case of:
186506c3fb27SDimitry Andric   // - The array type contains qualifiers.
186606c3fb27SDimitry Andric   // - In multidimensional arrays, the last LF_ARRAY entry contains the type.
186706c3fb27SDimitry Andric   TypeIndex TIArrayType;
186806c3fb27SDimitry Andric 
186906c3fb27SDimitry Andric   // For each dimension in the array, there is a LF_ARRAY entry. The last
187006c3fb27SDimitry Andric   // entry contains the array type, which can be a LF_MODIFIER in the case
187106c3fb27SDimitry Andric   // of the type being modified by a qualifier (const, etc).
187206c3fb27SDimitry Andric   ArrayRecord AR(AT);
187306c3fb27SDimitry Andric   CVType CVEntry = Record;
187406c3fb27SDimitry Andric   while (CVEntry.kind() == LF_ARRAY) {
187506c3fb27SDimitry Andric     // Create the subrange information, required by the logical view. Once
187606c3fb27SDimitry Andric     // the array has been processed, the dimension sizes will updated, as
187706c3fb27SDimitry Andric     // the sizes are a progression. For instance:
187806c3fb27SDimitry Andric     // sizeof(int) = 4
187906c3fb27SDimitry Andric     // int Array[2];        Sizes:  8          Dim: 8  /  4 -> [2]
188006c3fb27SDimitry Andric     // int Array[2][3];     Sizes: 24, 12      Dim: 24 / 12 -> [2]
188106c3fb27SDimitry Andric     //                                         Dim: 12 /  4 ->    [3]
188206c3fb27SDimitry Andric     // int Array[2][3][4];  sizes: 96, 48, 16  Dim: 96 / 48 -> [2]
188306c3fb27SDimitry Andric     //                                         Dim: 48 / 16 ->    [3]
188406c3fb27SDimitry Andric     //                                         Dim: 16 /  4 ->       [4]
188506c3fb27SDimitry Andric     AddSubrangeType(AR);
188606c3fb27SDimitry Andric     TIArrayType = TIElementType;
188706c3fb27SDimitry Andric 
188806c3fb27SDimitry Andric     // The current ElementType can be a modifier, in which case we need to
188906c3fb27SDimitry Andric     // get the type being modified.
189006c3fb27SDimitry Andric     // If TypeIndex is not a simple type, check if we have a qualified type.
189106c3fb27SDimitry Andric     if (!TIElementType.isSimple()) {
189206c3fb27SDimitry Andric       CVType CVElementType = Types.getType(TIElementType);
189306c3fb27SDimitry Andric       if (CVElementType.kind() == LF_MODIFIER) {
189406c3fb27SDimitry Andric         LVElement *QualifiedType =
189506c3fb27SDimitry Andric             Shared->TypeRecords.find(StreamTPI, TIElementType);
189606c3fb27SDimitry Andric         if (Error Err =
189706c3fb27SDimitry Andric                 finishVisitation(CVElementType, TIElementType, QualifiedType))
189806c3fb27SDimitry Andric           return Err;
189906c3fb27SDimitry Andric         // Get the TypeIndex of the type that the LF_MODIFIER modifies.
190006c3fb27SDimitry Andric         TIElementType = getModifiedType(CVElementType);
190106c3fb27SDimitry Andric       }
190206c3fb27SDimitry Andric     }
190306c3fb27SDimitry Andric     // Ends the traversal, as we have reached a simple type (int, char, etc).
190406c3fb27SDimitry Andric     if (TIElementType.isSimple())
190506c3fb27SDimitry Andric       break;
190606c3fb27SDimitry Andric 
190706c3fb27SDimitry Andric     // Read next dimension linked entry, if any.
190806c3fb27SDimitry Andric     CVEntry = Types.getType(TIElementType);
190906c3fb27SDimitry Andric     if (Error Err = TypeDeserializer::deserializeAs(
191006c3fb27SDimitry Andric             const_cast<CVType &>(CVEntry), AR)) {
191106c3fb27SDimitry Andric       consumeError(std::move(Err));
191206c3fb27SDimitry Andric       break;
191306c3fb27SDimitry Andric     }
191406c3fb27SDimitry Andric     TIElementType = AR.getElementType();
191506c3fb27SDimitry Andric     // NOTE: The typeindex has a value of: 0x0280.0000
191606c3fb27SDimitry Andric     getTrueType(TIElementType);
191706c3fb27SDimitry Andric   }
191806c3fb27SDimitry Andric 
191906c3fb27SDimitry Andric   Array->setName(AT.getName());
192006c3fb27SDimitry Andric   TIArrayType = Shared->ForwardReferences.remap(TIArrayType);
192106c3fb27SDimitry Andric   Array->setType(getElement(StreamTPI, TIArrayType));
192206c3fb27SDimitry Andric 
192306c3fb27SDimitry Andric   if (PrevSubrange)
192406c3fb27SDimitry Andric     // In the case of an aggregate type (class, struct, union, interface),
192506c3fb27SDimitry Andric     // get the aggregate size. As the original record is pointing to its
192606c3fb27SDimitry Andric     // reference, we have to update it.
192706c3fb27SDimitry Andric     if (uint64_t Size =
192806c3fb27SDimitry Andric             isAggregate(CVEntry)
192906c3fb27SDimitry Andric                 ? getSizeInBytesForTypeRecord(Types.getType(TIArrayType))
193006c3fb27SDimitry Andric                 : getSizeInBytesForTypeIndex(TIElementType))
193106c3fb27SDimitry Andric       PrevSubrange->setCount(PrevSubrange->getCount() / Size);
193206c3fb27SDimitry Andric 
193306c3fb27SDimitry Andric   return Error::success();
193406c3fb27SDimitry Andric }
193506c3fb27SDimitry Andric 
193606c3fb27SDimitry Andric // LF_BITFIELD (TPI)
visitKnownRecord(CVType & Record,BitFieldRecord & BF,TypeIndex TI,LVElement * Element)193706c3fb27SDimitry Andric Error LVLogicalVisitor::visitKnownRecord(CVType &Record, BitFieldRecord &BF,
193806c3fb27SDimitry Andric                                          TypeIndex TI, LVElement *Element) {
193906c3fb27SDimitry Andric   LLVM_DEBUG({
194006c3fb27SDimitry Andric     printTypeBegin(Record, TI, Element, StreamTPI);
194106c3fb27SDimitry Andric     printTypeIndex("Type", TI, StreamTPI);
194206c3fb27SDimitry Andric     W.printNumber("BitSize", BF.getBitSize());
194306c3fb27SDimitry Andric     W.printNumber("BitOffset", BF.getBitOffset());
194406c3fb27SDimitry Andric     printTypeEnd(Record);
194506c3fb27SDimitry Andric   });
194606c3fb27SDimitry Andric 
194706c3fb27SDimitry Andric   Element->setType(getElement(StreamTPI, BF.getType()));
194806c3fb27SDimitry Andric   Element->setBitSize(BF.getBitSize());
194906c3fb27SDimitry Andric   return Error::success();
195006c3fb27SDimitry Andric }
195106c3fb27SDimitry Andric 
195206c3fb27SDimitry Andric // LF_BUILDINFO (TPI)/(IPI)
visitKnownRecord(CVType & Record,BuildInfoRecord & BI,TypeIndex TI,LVElement * Element)195306c3fb27SDimitry Andric Error LVLogicalVisitor::visitKnownRecord(CVType &Record, BuildInfoRecord &BI,
195406c3fb27SDimitry Andric                                          TypeIndex TI, LVElement *Element) {
195506c3fb27SDimitry Andric   LLVM_DEBUG({
195606c3fb27SDimitry Andric     printTypeBegin(Record, TI, Element, StreamIPI);
195706c3fb27SDimitry Andric     W.printNumber("NumArgs", static_cast<uint32_t>(BI.getArgs().size()));
195806c3fb27SDimitry Andric     ListScope Arguments(W, "Arguments");
195906c3fb27SDimitry Andric     for (TypeIndex Arg : BI.getArgs())
196006c3fb27SDimitry Andric       printTypeIndex("ArgType", Arg, StreamIPI);
196106c3fb27SDimitry Andric     printTypeEnd(Record);
196206c3fb27SDimitry Andric   });
196306c3fb27SDimitry Andric 
196406c3fb27SDimitry Andric   // The given 'Element' refers to the current compilation unit.
196506c3fb27SDimitry Andric   // All the args are references into the TPI/IPI stream.
196606c3fb27SDimitry Andric   TypeIndex TIName = BI.getArgs()[BuildInfoRecord::BuildInfoArg::SourceFile];
196706c3fb27SDimitry Andric   std::string Name = std::string(ids().getTypeName(TIName));
196806c3fb27SDimitry Andric 
196906c3fb27SDimitry Andric   // There are cases where LF_BUILDINFO fields are empty.
197006c3fb27SDimitry Andric   if (!Name.empty())
197106c3fb27SDimitry Andric     Element->setName(Name);
197206c3fb27SDimitry Andric 
197306c3fb27SDimitry Andric   return Error::success();
197406c3fb27SDimitry Andric }
197506c3fb27SDimitry Andric 
197606c3fb27SDimitry Andric // LF_CLASS, LF_STRUCTURE, LF_INTERFACE (TPI)
visitKnownRecord(CVType & Record,ClassRecord & Class,TypeIndex TI,LVElement * Element)197706c3fb27SDimitry Andric Error LVLogicalVisitor::visitKnownRecord(CVType &Record, ClassRecord &Class,
197806c3fb27SDimitry Andric                                          TypeIndex TI, LVElement *Element) {
197906c3fb27SDimitry Andric   LLVM_DEBUG({
198006c3fb27SDimitry Andric     printTypeBegin(Record, TI, Element, StreamTPI);
198106c3fb27SDimitry Andric     W.printNumber("MemberCount", Class.getMemberCount());
198206c3fb27SDimitry Andric     printTypeIndex("FieldList", Class.getFieldList(), StreamTPI);
198306c3fb27SDimitry Andric     printTypeIndex("DerivedFrom", Class.getDerivationList(), StreamTPI);
198406c3fb27SDimitry Andric     printTypeIndex("VShape", Class.getVTableShape(), StreamTPI);
198506c3fb27SDimitry Andric     W.printNumber("SizeOf", Class.getSize());
198606c3fb27SDimitry Andric     W.printString("Name", Class.getName());
198706c3fb27SDimitry Andric     if (Class.hasUniqueName())
198806c3fb27SDimitry Andric       W.printString("UniqueName", Class.getUniqueName());
198906c3fb27SDimitry Andric     printTypeEnd(Record);
199006c3fb27SDimitry Andric   });
199106c3fb27SDimitry Andric 
199206c3fb27SDimitry Andric   if (Element->getIsFinalized())
199306c3fb27SDimitry Andric     return Error::success();
199406c3fb27SDimitry Andric   Element->setIsFinalized();
199506c3fb27SDimitry Andric 
199606c3fb27SDimitry Andric   LVScopeAggregate *Scope = static_cast<LVScopeAggregate *>(Element);
199706c3fb27SDimitry Andric   if (!Scope)
199806c3fb27SDimitry Andric     return Error::success();
199906c3fb27SDimitry Andric 
200006c3fb27SDimitry Andric   Scope->setName(Class.getName());
200106c3fb27SDimitry Andric   if (Class.hasUniqueName())
200206c3fb27SDimitry Andric     Scope->setLinkageName(Class.getUniqueName());
200306c3fb27SDimitry Andric 
200406c3fb27SDimitry Andric   if (Class.isNested()) {
200506c3fb27SDimitry Andric     Scope->setIsNested();
200606c3fb27SDimitry Andric     createParents(Class.getName(), Scope);
200706c3fb27SDimitry Andric   }
200806c3fb27SDimitry Andric 
200906c3fb27SDimitry Andric   if (Class.isScoped())
201006c3fb27SDimitry Andric     Scope->setIsScoped();
201106c3fb27SDimitry Andric 
201206c3fb27SDimitry Andric   // Nested types will be added to their parents at creation. The forward
201306c3fb27SDimitry Andric   // references are only processed to finish the referenced element creation.
201406c3fb27SDimitry Andric   if (!(Class.isNested() || Class.isScoped())) {
201506c3fb27SDimitry Andric     if (LVScope *Namespace = Shared->NamespaceDeduction.get(Class.getName()))
201606c3fb27SDimitry Andric       Namespace->addElement(Scope);
201706c3fb27SDimitry Andric     else
201806c3fb27SDimitry Andric       Reader->getCompileUnit()->addElement(Scope);
201906c3fb27SDimitry Andric   }
202006c3fb27SDimitry Andric 
202106c3fb27SDimitry Andric   LazyRandomTypeCollection &Types = types();
202206c3fb27SDimitry Andric   TypeIndex TIFieldList = Class.getFieldList();
202306c3fb27SDimitry Andric   if (TIFieldList.isNoneType()) {
202406c3fb27SDimitry Andric     TypeIndex ForwardType = Shared->ForwardReferences.find(Class.getName());
202506c3fb27SDimitry Andric     if (!ForwardType.isNoneType()) {
202606c3fb27SDimitry Andric       CVType CVReference = Types.getType(ForwardType);
202706c3fb27SDimitry Andric       TypeRecordKind RK = static_cast<TypeRecordKind>(CVReference.kind());
202806c3fb27SDimitry Andric       ClassRecord ReferenceRecord(RK);
202906c3fb27SDimitry Andric       if (Error Err = TypeDeserializer::deserializeAs(
203006c3fb27SDimitry Andric               const_cast<CVType &>(CVReference), ReferenceRecord))
203106c3fb27SDimitry Andric         return Err;
203206c3fb27SDimitry Andric       TIFieldList = ReferenceRecord.getFieldList();
203306c3fb27SDimitry Andric     }
203406c3fb27SDimitry Andric   }
203506c3fb27SDimitry Andric 
203606c3fb27SDimitry Andric   if (!TIFieldList.isNoneType()) {
203706c3fb27SDimitry Andric     // Pass down the TypeIndex 'TI' for the aggregate containing the field list.
203806c3fb27SDimitry Andric     CVType CVFieldList = Types.getType(TIFieldList);
203906c3fb27SDimitry Andric     if (Error Err = finishVisitation(CVFieldList, TI, Scope))
204006c3fb27SDimitry Andric       return Err;
204106c3fb27SDimitry Andric   }
204206c3fb27SDimitry Andric 
204306c3fb27SDimitry Andric   return Error::success();
204406c3fb27SDimitry Andric }
204506c3fb27SDimitry Andric 
204606c3fb27SDimitry Andric // LF_ENUM (TPI)
visitKnownRecord(CVType & Record,EnumRecord & Enum,TypeIndex TI,LVElement * Element)204706c3fb27SDimitry Andric Error LVLogicalVisitor::visitKnownRecord(CVType &Record, EnumRecord &Enum,
204806c3fb27SDimitry Andric                                          TypeIndex TI, LVElement *Element) {
204906c3fb27SDimitry Andric   LLVM_DEBUG({
205006c3fb27SDimitry Andric     printTypeBegin(Record, TI, Element, StreamTPI);
205106c3fb27SDimitry Andric     W.printNumber("NumEnumerators", Enum.getMemberCount());
205206c3fb27SDimitry Andric     printTypeIndex("UnderlyingType", Enum.getUnderlyingType(), StreamTPI);
205306c3fb27SDimitry Andric     printTypeIndex("FieldListType", Enum.getFieldList(), StreamTPI);
205406c3fb27SDimitry Andric     W.printString("Name", Enum.getName());
205506c3fb27SDimitry Andric     printTypeEnd(Record);
205606c3fb27SDimitry Andric   });
205706c3fb27SDimitry Andric 
205806c3fb27SDimitry Andric   LVScopeEnumeration *Scope = static_cast<LVScopeEnumeration *>(Element);
205906c3fb27SDimitry Andric   if (!Scope)
206006c3fb27SDimitry Andric     return Error::success();
206106c3fb27SDimitry Andric 
206206c3fb27SDimitry Andric   if (Scope->getIsFinalized())
206306c3fb27SDimitry Andric     return Error::success();
206406c3fb27SDimitry Andric   Scope->setIsFinalized();
206506c3fb27SDimitry Andric 
206606c3fb27SDimitry Andric   // Set the name, as in the case of nested, it would determine the relation
206706c3fb27SDimitry Andric   // to any potential parent, via the LF_NESTTYPE record.
206806c3fb27SDimitry Andric   Scope->setName(Enum.getName());
206906c3fb27SDimitry Andric   if (Enum.hasUniqueName())
207006c3fb27SDimitry Andric     Scope->setLinkageName(Enum.getUniqueName());
207106c3fb27SDimitry Andric 
207206c3fb27SDimitry Andric   Scope->setType(getElement(StreamTPI, Enum.getUnderlyingType()));
207306c3fb27SDimitry Andric 
207406c3fb27SDimitry Andric   if (Enum.isNested()) {
207506c3fb27SDimitry Andric     Scope->setIsNested();
207606c3fb27SDimitry Andric     createParents(Enum.getName(), Scope);
207706c3fb27SDimitry Andric   }
207806c3fb27SDimitry Andric 
207906c3fb27SDimitry Andric   if (Enum.isScoped()) {
208006c3fb27SDimitry Andric     Scope->setIsScoped();
208106c3fb27SDimitry Andric     Scope->setIsEnumClass();
208206c3fb27SDimitry Andric   }
208306c3fb27SDimitry Andric 
208406c3fb27SDimitry Andric   // Nested types will be added to their parents at creation.
208506c3fb27SDimitry Andric   if (!(Enum.isNested() || Enum.isScoped())) {
208606c3fb27SDimitry Andric     if (LVScope *Namespace = Shared->NamespaceDeduction.get(Enum.getName()))
208706c3fb27SDimitry Andric       Namespace->addElement(Scope);
208806c3fb27SDimitry Andric     else
208906c3fb27SDimitry Andric       Reader->getCompileUnit()->addElement(Scope);
209006c3fb27SDimitry Andric   }
209106c3fb27SDimitry Andric 
209206c3fb27SDimitry Andric   TypeIndex TIFieldList = Enum.getFieldList();
209306c3fb27SDimitry Andric   if (!TIFieldList.isNoneType()) {
209406c3fb27SDimitry Andric     LazyRandomTypeCollection &Types = types();
209506c3fb27SDimitry Andric     CVType CVFieldList = Types.getType(TIFieldList);
209606c3fb27SDimitry Andric     if (Error Err = finishVisitation(CVFieldList, TIFieldList, Scope))
209706c3fb27SDimitry Andric       return Err;
209806c3fb27SDimitry Andric   }
209906c3fb27SDimitry Andric 
210006c3fb27SDimitry Andric   return Error::success();
210106c3fb27SDimitry Andric }
210206c3fb27SDimitry Andric 
210306c3fb27SDimitry Andric // LF_FIELDLIST (TPI)
visitKnownRecord(CVType & Record,FieldListRecord & FieldList,TypeIndex TI,LVElement * Element)210406c3fb27SDimitry Andric Error LVLogicalVisitor::visitKnownRecord(CVType &Record,
210506c3fb27SDimitry Andric                                          FieldListRecord &FieldList,
210606c3fb27SDimitry Andric                                          TypeIndex TI, LVElement *Element) {
210706c3fb27SDimitry Andric   LLVM_DEBUG({
210806c3fb27SDimitry Andric     printTypeBegin(Record, TI, Element, StreamTPI);
210906c3fb27SDimitry Andric     printTypeEnd(Record);
211006c3fb27SDimitry Andric   });
211106c3fb27SDimitry Andric 
211206c3fb27SDimitry Andric   if (Error Err = visitFieldListMemberStream(TI, Element, FieldList.Data))
211306c3fb27SDimitry Andric     return Err;
211406c3fb27SDimitry Andric 
211506c3fb27SDimitry Andric   return Error::success();
211606c3fb27SDimitry Andric }
211706c3fb27SDimitry Andric 
211806c3fb27SDimitry Andric // LF_FUNC_ID (TPI)/(IPI)
visitKnownRecord(CVType & Record,FuncIdRecord & Func,TypeIndex TI,LVElement * Element)211906c3fb27SDimitry Andric Error LVLogicalVisitor::visitKnownRecord(CVType &Record, FuncIdRecord &Func,
212006c3fb27SDimitry Andric                                          TypeIndex TI, LVElement *Element) {
212106c3fb27SDimitry Andric   // ParentScope and FunctionType are references into the TPI stream.
212206c3fb27SDimitry Andric   LLVM_DEBUG({
212306c3fb27SDimitry Andric     printTypeBegin(Record, TI, Element, StreamIPI);
212406c3fb27SDimitry Andric     printTypeIndex("ParentScope", Func.getParentScope(), StreamTPI);
212506c3fb27SDimitry Andric     printTypeIndex("FunctionType", Func.getFunctionType(), StreamTPI);
212606c3fb27SDimitry Andric     W.printString("Name", Func.getName());
212706c3fb27SDimitry Andric     printTypeEnd(Record);
212806c3fb27SDimitry Andric   });
212906c3fb27SDimitry Andric 
213006c3fb27SDimitry Andric   // The TypeIndex (LF_PROCEDURE) returned by 'getFunctionType' is the
213106c3fb27SDimitry Andric   // function propotype, we need to use the function definition.
213206c3fb27SDimitry Andric   if (LVScope *FunctionDcl = static_cast<LVScope *>(Element)) {
213306c3fb27SDimitry Andric     // For inlined functions, the inlined instance has been already processed
213406c3fb27SDimitry Andric     // (all its information is contained in the Symbols section).
213506c3fb27SDimitry Andric     // 'Element' points to the created 'abstract' (out-of-line) function.
213606c3fb27SDimitry Andric     // Use the parent scope information to allocate it to the correct scope.
213706c3fb27SDimitry Andric     LazyRandomTypeCollection &Types = types();
213806c3fb27SDimitry Andric     TypeIndex TIParent = Func.getParentScope();
213906c3fb27SDimitry Andric     if (FunctionDcl->getIsInlinedAbstract()) {
214006c3fb27SDimitry Andric       FunctionDcl->setName(Func.getName());
214106c3fb27SDimitry Andric       if (TIParent.isNoneType())
214206c3fb27SDimitry Andric         Reader->getCompileUnit()->addElement(FunctionDcl);
214306c3fb27SDimitry Andric     }
214406c3fb27SDimitry Andric 
214506c3fb27SDimitry Andric     if (!TIParent.isNoneType()) {
214606c3fb27SDimitry Andric       CVType CVParentScope = ids().getType(TIParent);
214706c3fb27SDimitry Andric       if (Error Err = finishVisitation(CVParentScope, TIParent, FunctionDcl))
214806c3fb27SDimitry Andric         return Err;
214906c3fb27SDimitry Andric     }
215006c3fb27SDimitry Andric 
215106c3fb27SDimitry Andric     TypeIndex TIFunctionType = Func.getFunctionType();
215206c3fb27SDimitry Andric     CVType CVFunctionType = Types.getType(TIFunctionType);
215306c3fb27SDimitry Andric     if (Error Err =
215406c3fb27SDimitry Andric             finishVisitation(CVFunctionType, TIFunctionType, FunctionDcl))
215506c3fb27SDimitry Andric       return Err;
215606c3fb27SDimitry Andric 
215706c3fb27SDimitry Andric     FunctionDcl->setIsFinalized();
215806c3fb27SDimitry Andric   }
215906c3fb27SDimitry Andric 
216006c3fb27SDimitry Andric   return Error::success();
216106c3fb27SDimitry Andric }
216206c3fb27SDimitry Andric 
216306c3fb27SDimitry Andric // LF_LABEL (TPI)
visitKnownRecord(CVType & Record,LabelRecord & LR,TypeIndex TI,LVElement * Element)216406c3fb27SDimitry Andric Error LVLogicalVisitor::visitKnownRecord(CVType &Record, LabelRecord &LR,
216506c3fb27SDimitry Andric                                          TypeIndex TI, LVElement *Element) {
216606c3fb27SDimitry Andric   LLVM_DEBUG({
216706c3fb27SDimitry Andric     printTypeBegin(Record, TI, Element, StreamTPI);
216806c3fb27SDimitry Andric     printTypeEnd(Record);
216906c3fb27SDimitry Andric   });
217006c3fb27SDimitry Andric   return Error::success();
217106c3fb27SDimitry Andric }
217206c3fb27SDimitry Andric 
217306c3fb27SDimitry Andric // LF_MFUNC_ID (TPI)/(IPI)
visitKnownRecord(CVType & Record,MemberFuncIdRecord & Id,TypeIndex TI,LVElement * Element)217406c3fb27SDimitry Andric Error LVLogicalVisitor::visitKnownRecord(CVType &Record, MemberFuncIdRecord &Id,
217506c3fb27SDimitry Andric                                          TypeIndex TI, LVElement *Element) {
217606c3fb27SDimitry Andric   // ClassType and FunctionType are references into the TPI stream.
217706c3fb27SDimitry Andric   LLVM_DEBUG({
217806c3fb27SDimitry Andric     printTypeBegin(Record, TI, Element, StreamIPI);
217906c3fb27SDimitry Andric     printTypeIndex("ClassType", Id.getClassType(), StreamTPI);
218006c3fb27SDimitry Andric     printTypeIndex("FunctionType", Id.getFunctionType(), StreamTPI);
218106c3fb27SDimitry Andric     W.printString("Name", Id.getName());
218206c3fb27SDimitry Andric     printTypeEnd(Record);
218306c3fb27SDimitry Andric   });
218406c3fb27SDimitry Andric 
218506c3fb27SDimitry Andric   LVScope *FunctionDcl = static_cast<LVScope *>(Element);
218606c3fb27SDimitry Andric   if (FunctionDcl->getIsInlinedAbstract()) {
218706c3fb27SDimitry Andric     // For inlined functions, the inlined instance has been already processed
218806c3fb27SDimitry Andric     // (all its information is contained in the Symbols section).
218906c3fb27SDimitry Andric     // 'Element' points to the created 'abstract' (out-of-line) function.
219006c3fb27SDimitry Andric     // Use the parent scope information to allocate it to the correct scope.
219106c3fb27SDimitry Andric     if (LVScope *Class = static_cast<LVScope *>(
219206c3fb27SDimitry Andric             Shared->TypeRecords.find(StreamTPI, Id.getClassType())))
219306c3fb27SDimitry Andric       Class->addElement(FunctionDcl);
219406c3fb27SDimitry Andric   }
219506c3fb27SDimitry Andric 
219606c3fb27SDimitry Andric   TypeIndex TIFunctionType = Id.getFunctionType();
219706c3fb27SDimitry Andric   CVType CVFunction = types().getType(TIFunctionType);
219806c3fb27SDimitry Andric   if (Error Err = finishVisitation(CVFunction, TIFunctionType, Element))
219906c3fb27SDimitry Andric     return Err;
220006c3fb27SDimitry Andric 
220106c3fb27SDimitry Andric   return Error::success();
220206c3fb27SDimitry Andric }
220306c3fb27SDimitry Andric 
220406c3fb27SDimitry Andric // LF_MFUNCTION (TPI)
visitKnownRecord(CVType & Record,MemberFunctionRecord & MF,TypeIndex TI,LVElement * Element)220506c3fb27SDimitry Andric Error LVLogicalVisitor::visitKnownRecord(CVType &Record,
220606c3fb27SDimitry Andric                                          MemberFunctionRecord &MF, TypeIndex TI,
220706c3fb27SDimitry Andric                                          LVElement *Element) {
220806c3fb27SDimitry Andric   LLVM_DEBUG({
220906c3fb27SDimitry Andric     printTypeBegin(Record, TI, Element, StreamTPI);
221006c3fb27SDimitry Andric     printTypeIndex("ReturnType", MF.getReturnType(), StreamTPI);
221106c3fb27SDimitry Andric     printTypeIndex("ClassType", MF.getClassType(), StreamTPI);
221206c3fb27SDimitry Andric     printTypeIndex("ThisType", MF.getThisType(), StreamTPI);
221306c3fb27SDimitry Andric     W.printNumber("NumParameters", MF.getParameterCount());
221406c3fb27SDimitry Andric     printTypeIndex("ArgListType", MF.getArgumentList(), StreamTPI);
221506c3fb27SDimitry Andric     W.printNumber("ThisAdjustment", MF.getThisPointerAdjustment());
221606c3fb27SDimitry Andric     printTypeEnd(Record);
221706c3fb27SDimitry Andric   });
221806c3fb27SDimitry Andric 
221906c3fb27SDimitry Andric   if (LVScope *MemberFunction = static_cast<LVScope *>(Element)) {
222006c3fb27SDimitry Andric     LVElement *Class = getElement(StreamTPI, MF.getClassType());
222106c3fb27SDimitry Andric 
222206c3fb27SDimitry Andric     MemberFunction->setIsFinalized();
222306c3fb27SDimitry Andric     MemberFunction->setType(getElement(StreamTPI, MF.getReturnType()));
222406c3fb27SDimitry Andric     MemberFunction->setOffset(TI.getIndex());
222506c3fb27SDimitry Andric     MemberFunction->setOffsetFromTypeIndex();
222606c3fb27SDimitry Andric 
222706c3fb27SDimitry Andric     if (ProcessArgumentList) {
222806c3fb27SDimitry Andric       ProcessArgumentList = false;
222906c3fb27SDimitry Andric 
223006c3fb27SDimitry Andric       if (!MemberFunction->getIsStatic()) {
223106c3fb27SDimitry Andric         LVElement *ThisPointer = getElement(StreamTPI, MF.getThisType());
223206c3fb27SDimitry Andric         // When creating the 'this' pointer, check if it points to a reference.
223306c3fb27SDimitry Andric         ThisPointer->setType(Class);
223406c3fb27SDimitry Andric         LVSymbol *This =
223506c3fb27SDimitry Andric             createParameter(ThisPointer, StringRef(), MemberFunction);
223606c3fb27SDimitry Andric         This->setIsArtificial();
223706c3fb27SDimitry Andric       }
223806c3fb27SDimitry Andric 
223906c3fb27SDimitry Andric       // Create formal parameters.
224006c3fb27SDimitry Andric       LazyRandomTypeCollection &Types = types();
224106c3fb27SDimitry Andric       CVType CVArguments = Types.getType(MF.getArgumentList());
224206c3fb27SDimitry Andric       if (Error Err = finishVisitation(CVArguments, MF.getArgumentList(),
224306c3fb27SDimitry Andric                                        MemberFunction))
224406c3fb27SDimitry Andric         return Err;
224506c3fb27SDimitry Andric     }
224606c3fb27SDimitry Andric   }
224706c3fb27SDimitry Andric 
224806c3fb27SDimitry Andric   return Error::success();
224906c3fb27SDimitry Andric }
225006c3fb27SDimitry Andric 
225106c3fb27SDimitry Andric // LF_METHODLIST (TPI)
visitKnownRecord(CVType & Record,MethodOverloadListRecord & Overloads,TypeIndex TI,LVElement * Element)225206c3fb27SDimitry Andric Error LVLogicalVisitor::visitKnownRecord(CVType &Record,
225306c3fb27SDimitry Andric                                          MethodOverloadListRecord &Overloads,
225406c3fb27SDimitry Andric                                          TypeIndex TI, LVElement *Element) {
225506c3fb27SDimitry Andric   LLVM_DEBUG({
225606c3fb27SDimitry Andric     printTypeBegin(Record, TI, Element, StreamTPI);
225706c3fb27SDimitry Andric     printTypeEnd(Record);
225806c3fb27SDimitry Andric   });
225906c3fb27SDimitry Andric 
226006c3fb27SDimitry Andric   for (OneMethodRecord &Method : Overloads.Methods) {
226106c3fb27SDimitry Andric     CVMemberRecord Record;
226206c3fb27SDimitry Andric     Record.Kind = LF_METHOD;
226306c3fb27SDimitry Andric     Method.Name = OverloadedMethodName;
226406c3fb27SDimitry Andric     if (Error Err = visitKnownMember(Record, Method, TI, Element))
226506c3fb27SDimitry Andric       return Err;
226606c3fb27SDimitry Andric   }
226706c3fb27SDimitry Andric 
226806c3fb27SDimitry Andric   return Error::success();
226906c3fb27SDimitry Andric }
227006c3fb27SDimitry Andric 
227106c3fb27SDimitry Andric // LF_MODIFIER (TPI)
visitKnownRecord(CVType & Record,ModifierRecord & Mod,TypeIndex TI,LVElement * Element)227206c3fb27SDimitry Andric Error LVLogicalVisitor::visitKnownRecord(CVType &Record, ModifierRecord &Mod,
227306c3fb27SDimitry Andric                                          TypeIndex TI, LVElement *Element) {
227406c3fb27SDimitry Andric   LLVM_DEBUG({
227506c3fb27SDimitry Andric     printTypeBegin(Record, TI, Element, StreamTPI);
227606c3fb27SDimitry Andric     printTypeIndex("ModifiedType", Mod.getModifiedType(), StreamTPI);
227706c3fb27SDimitry Andric     printTypeEnd(Record);
227806c3fb27SDimitry Andric   });
227906c3fb27SDimitry Andric 
228006c3fb27SDimitry Andric   // Create the modified type, which will be attached to the type(s) that
228106c3fb27SDimitry Andric   // contains the modifiers.
228206c3fb27SDimitry Andric   LVElement *ModifiedType = getElement(StreamTPI, Mod.getModifiedType());
228306c3fb27SDimitry Andric 
228406c3fb27SDimitry Andric   // At this point the types recording the qualifiers do not have a
228506c3fb27SDimitry Andric   // scope parent. They must be assigned to the current compile unit.
228606c3fb27SDimitry Andric   LVScopeCompileUnit *CompileUnit = Reader->getCompileUnit();
228706c3fb27SDimitry Andric 
228806c3fb27SDimitry Andric   // The incoming element does not have a defined kind. Use the given
228906c3fb27SDimitry Andric   // modifiers to complete its type. A type can have more than one modifier;
229006c3fb27SDimitry Andric   // in that case, we have to create an extra type to have the other modifier.
229106c3fb27SDimitry Andric   LVType *LastLink = static_cast<LVType *>(Element);
229206c3fb27SDimitry Andric   if (!LastLink->getParentScope())
229306c3fb27SDimitry Andric     CompileUnit->addElement(LastLink);
229406c3fb27SDimitry Andric 
229506c3fb27SDimitry Andric   bool SeenModifier = false;
229606c3fb27SDimitry Andric   uint16_t Mods = static_cast<uint16_t>(Mod.getModifiers());
229706c3fb27SDimitry Andric   if (Mods & uint16_t(ModifierOptions::Const)) {
229806c3fb27SDimitry Andric     SeenModifier = true;
229906c3fb27SDimitry Andric     LastLink->setTag(dwarf::DW_TAG_const_type);
230006c3fb27SDimitry Andric     LastLink->setIsConst();
230106c3fb27SDimitry Andric     LastLink->setName("const");
230206c3fb27SDimitry Andric   }
230306c3fb27SDimitry Andric   if (Mods & uint16_t(ModifierOptions::Volatile)) {
230406c3fb27SDimitry Andric     if (SeenModifier) {
230506c3fb27SDimitry Andric       LVType *Volatile = Reader->createType();
230606c3fb27SDimitry Andric       Volatile->setIsModifier();
230706c3fb27SDimitry Andric       LastLink->setType(Volatile);
230806c3fb27SDimitry Andric       LastLink = Volatile;
230906c3fb27SDimitry Andric       CompileUnit->addElement(LastLink);
231006c3fb27SDimitry Andric     }
231106c3fb27SDimitry Andric     LastLink->setTag(dwarf::DW_TAG_volatile_type);
231206c3fb27SDimitry Andric     LastLink->setIsVolatile();
231306c3fb27SDimitry Andric     LastLink->setName("volatile");
231406c3fb27SDimitry Andric   }
231506c3fb27SDimitry Andric   if (Mods & uint16_t(ModifierOptions::Unaligned)) {
231606c3fb27SDimitry Andric     if (SeenModifier) {
231706c3fb27SDimitry Andric       LVType *Unaligned = Reader->createType();
231806c3fb27SDimitry Andric       Unaligned->setIsModifier();
231906c3fb27SDimitry Andric       LastLink->setType(Unaligned);
232006c3fb27SDimitry Andric       LastLink = Unaligned;
232106c3fb27SDimitry Andric       CompileUnit->addElement(LastLink);
232206c3fb27SDimitry Andric     }
232306c3fb27SDimitry Andric     LastLink->setTag(dwarf::DW_TAG_unaligned);
232406c3fb27SDimitry Andric     LastLink->setIsUnaligned();
232506c3fb27SDimitry Andric     LastLink->setName("unaligned");
232606c3fb27SDimitry Andric   }
232706c3fb27SDimitry Andric 
232806c3fb27SDimitry Andric   LastLink->setType(ModifiedType);
232906c3fb27SDimitry Andric   return Error::success();
233006c3fb27SDimitry Andric }
233106c3fb27SDimitry Andric 
233206c3fb27SDimitry Andric // LF_POINTER (TPI)
visitKnownRecord(CVType & Record,PointerRecord & Ptr,TypeIndex TI,LVElement * Element)233306c3fb27SDimitry Andric Error LVLogicalVisitor::visitKnownRecord(CVType &Record, PointerRecord &Ptr,
233406c3fb27SDimitry Andric                                          TypeIndex TI, LVElement *Element) {
233506c3fb27SDimitry Andric   LLVM_DEBUG({
233606c3fb27SDimitry Andric     printTypeBegin(Record, TI, Element, StreamTPI);
233706c3fb27SDimitry Andric     printTypeIndex("PointeeType", Ptr.getReferentType(), StreamTPI);
233806c3fb27SDimitry Andric     W.printNumber("IsFlat", Ptr.isFlat());
233906c3fb27SDimitry Andric     W.printNumber("IsConst", Ptr.isConst());
234006c3fb27SDimitry Andric     W.printNumber("IsVolatile", Ptr.isVolatile());
234106c3fb27SDimitry Andric     W.printNumber("IsUnaligned", Ptr.isUnaligned());
234206c3fb27SDimitry Andric     W.printNumber("IsRestrict", Ptr.isRestrict());
234306c3fb27SDimitry Andric     W.printNumber("IsThisPtr&", Ptr.isLValueReferenceThisPtr());
234406c3fb27SDimitry Andric     W.printNumber("IsThisPtr&&", Ptr.isRValueReferenceThisPtr());
234506c3fb27SDimitry Andric     W.printNumber("SizeOf", Ptr.getSize());
234606c3fb27SDimitry Andric 
234706c3fb27SDimitry Andric     if (Ptr.isPointerToMember()) {
234806c3fb27SDimitry Andric       const MemberPointerInfo &MI = Ptr.getMemberInfo();
234906c3fb27SDimitry Andric       printTypeIndex("ClassType", MI.getContainingType(), StreamTPI);
235006c3fb27SDimitry Andric     }
235106c3fb27SDimitry Andric     printTypeEnd(Record);
235206c3fb27SDimitry Andric   });
235306c3fb27SDimitry Andric 
235406c3fb27SDimitry Andric   // Find the pointed-to type.
235506c3fb27SDimitry Andric   LVType *Pointer = static_cast<LVType *>(Element);
235606c3fb27SDimitry Andric   LVElement *Pointee = nullptr;
235706c3fb27SDimitry Andric 
235806c3fb27SDimitry Andric   PointerMode Mode = Ptr.getMode();
235906c3fb27SDimitry Andric   Pointee = Ptr.isPointerToMember()
236006c3fb27SDimitry Andric                 ? Shared->TypeRecords.find(StreamTPI, Ptr.getReferentType())
236106c3fb27SDimitry Andric                 : getElement(StreamTPI, Ptr.getReferentType());
236206c3fb27SDimitry Andric 
236306c3fb27SDimitry Andric   // At this point the types recording the qualifiers do not have a
236406c3fb27SDimitry Andric   // scope parent. They must be assigned to the current compile unit.
236506c3fb27SDimitry Andric   LVScopeCompileUnit *CompileUnit = Reader->getCompileUnit();
236606c3fb27SDimitry Andric 
236706c3fb27SDimitry Andric   // Order for the different modifiers:
236806c3fb27SDimitry Andric   // <restrict> <pointer, Reference, ValueReference> <const, volatile>
236906c3fb27SDimitry Andric   // Const and volatile already processed.
237006c3fb27SDimitry Andric   bool SeenModifier = false;
237106c3fb27SDimitry Andric   LVType *LastLink = Pointer;
237206c3fb27SDimitry Andric   if (!LastLink->getParentScope())
237306c3fb27SDimitry Andric     CompileUnit->addElement(LastLink);
237406c3fb27SDimitry Andric 
237506c3fb27SDimitry Andric   if (Ptr.isRestrict()) {
237606c3fb27SDimitry Andric     SeenModifier = true;
237706c3fb27SDimitry Andric     LVType *Restrict = Reader->createType();
237806c3fb27SDimitry Andric     Restrict->setTag(dwarf::DW_TAG_restrict_type);
237906c3fb27SDimitry Andric     Restrict->setIsRestrict();
238006c3fb27SDimitry Andric     Restrict->setName("restrict");
238106c3fb27SDimitry Andric     LastLink->setType(Restrict);
238206c3fb27SDimitry Andric     LastLink = Restrict;
238306c3fb27SDimitry Andric     CompileUnit->addElement(LastLink);
238406c3fb27SDimitry Andric   }
238506c3fb27SDimitry Andric   if (Mode == PointerMode::LValueReference) {
238606c3fb27SDimitry Andric     if (SeenModifier) {
238706c3fb27SDimitry Andric       LVType *LReference = Reader->createType();
238806c3fb27SDimitry Andric       LReference->setIsModifier();
238906c3fb27SDimitry Andric       LastLink->setType(LReference);
239006c3fb27SDimitry Andric       LastLink = LReference;
239106c3fb27SDimitry Andric       CompileUnit->addElement(LastLink);
239206c3fb27SDimitry Andric     }
239306c3fb27SDimitry Andric     LastLink->setTag(dwarf::DW_TAG_reference_type);
239406c3fb27SDimitry Andric     LastLink->setIsReference();
239506c3fb27SDimitry Andric     LastLink->setName("&");
239606c3fb27SDimitry Andric   }
239706c3fb27SDimitry Andric   if (Mode == PointerMode::RValueReference) {
239806c3fb27SDimitry Andric     if (SeenModifier) {
239906c3fb27SDimitry Andric       LVType *RReference = Reader->createType();
240006c3fb27SDimitry Andric       RReference->setIsModifier();
240106c3fb27SDimitry Andric       LastLink->setType(RReference);
240206c3fb27SDimitry Andric       LastLink = RReference;
240306c3fb27SDimitry Andric       CompileUnit->addElement(LastLink);
240406c3fb27SDimitry Andric     }
240506c3fb27SDimitry Andric     LastLink->setTag(dwarf::DW_TAG_rvalue_reference_type);
240606c3fb27SDimitry Andric     LastLink->setIsRvalueReference();
240706c3fb27SDimitry Andric     LastLink->setName("&&");
240806c3fb27SDimitry Andric   }
240906c3fb27SDimitry Andric 
241006c3fb27SDimitry Andric   // When creating the pointer, check if it points to a reference.
241106c3fb27SDimitry Andric   LastLink->setType(Pointee);
241206c3fb27SDimitry Andric   return Error::success();
241306c3fb27SDimitry Andric }
241406c3fb27SDimitry Andric 
241506c3fb27SDimitry Andric // LF_PROCEDURE (TPI)
visitKnownRecord(CVType & Record,ProcedureRecord & Proc,TypeIndex TI,LVElement * Element)241606c3fb27SDimitry Andric Error LVLogicalVisitor::visitKnownRecord(CVType &Record, ProcedureRecord &Proc,
241706c3fb27SDimitry Andric                                          TypeIndex TI, LVElement *Element) {
241806c3fb27SDimitry Andric   LLVM_DEBUG({
241906c3fb27SDimitry Andric     printTypeBegin(Record, TI, Element, StreamTPI);
242006c3fb27SDimitry Andric     printTypeIndex("ReturnType", Proc.getReturnType(), StreamTPI);
242106c3fb27SDimitry Andric     W.printNumber("NumParameters", Proc.getParameterCount());
242206c3fb27SDimitry Andric     printTypeIndex("ArgListType", Proc.getArgumentList(), StreamTPI);
242306c3fb27SDimitry Andric     printTypeEnd(Record);
242406c3fb27SDimitry Andric   });
242506c3fb27SDimitry Andric 
242606c3fb27SDimitry Andric   // There is no need to traverse the argument list, as the CodeView format
242706c3fb27SDimitry Andric   // declares the parameters as a 'S_LOCAL' symbol tagged as parameter.
242806c3fb27SDimitry Andric   // Only process parameters when dealing with inline functions.
242906c3fb27SDimitry Andric   if (LVScope *FunctionDcl = static_cast<LVScope *>(Element)) {
243006c3fb27SDimitry Andric     FunctionDcl->setType(getElement(StreamTPI, Proc.getReturnType()));
243106c3fb27SDimitry Andric 
243206c3fb27SDimitry Andric     if (ProcessArgumentList) {
243306c3fb27SDimitry Andric       ProcessArgumentList = false;
243406c3fb27SDimitry Andric       // Create formal parameters.
243506c3fb27SDimitry Andric       LazyRandomTypeCollection &Types = types();
243606c3fb27SDimitry Andric       CVType CVArguments = Types.getType(Proc.getArgumentList());
243706c3fb27SDimitry Andric       if (Error Err = finishVisitation(CVArguments, Proc.getArgumentList(),
243806c3fb27SDimitry Andric                                        FunctionDcl))
243906c3fb27SDimitry Andric         return Err;
244006c3fb27SDimitry Andric     }
244106c3fb27SDimitry Andric   }
244206c3fb27SDimitry Andric 
244306c3fb27SDimitry Andric   return Error::success();
244406c3fb27SDimitry Andric }
244506c3fb27SDimitry Andric 
244606c3fb27SDimitry Andric // LF_UNION (TPI)
visitKnownRecord(CVType & Record,UnionRecord & Union,TypeIndex TI,LVElement * Element)244706c3fb27SDimitry Andric Error LVLogicalVisitor::visitKnownRecord(CVType &Record, UnionRecord &Union,
244806c3fb27SDimitry Andric                                          TypeIndex TI, LVElement *Element) {
244906c3fb27SDimitry Andric   LLVM_DEBUG({
245006c3fb27SDimitry Andric     printTypeBegin(Record, TI, Element, StreamTPI);
245106c3fb27SDimitry Andric     W.printNumber("MemberCount", Union.getMemberCount());
245206c3fb27SDimitry Andric     printTypeIndex("FieldList", Union.getFieldList(), StreamTPI);
245306c3fb27SDimitry Andric     W.printNumber("SizeOf", Union.getSize());
245406c3fb27SDimitry Andric     W.printString("Name", Union.getName());
245506c3fb27SDimitry Andric     if (Union.hasUniqueName())
245606c3fb27SDimitry Andric       W.printString("UniqueName", Union.getUniqueName());
245706c3fb27SDimitry Andric     printTypeEnd(Record);
245806c3fb27SDimitry Andric   });
245906c3fb27SDimitry Andric 
246006c3fb27SDimitry Andric   LVScopeAggregate *Scope = static_cast<LVScopeAggregate *>(Element);
246106c3fb27SDimitry Andric   if (!Scope)
246206c3fb27SDimitry Andric     return Error::success();
246306c3fb27SDimitry Andric 
246406c3fb27SDimitry Andric   if (Scope->getIsFinalized())
246506c3fb27SDimitry Andric     return Error::success();
246606c3fb27SDimitry Andric   Scope->setIsFinalized();
246706c3fb27SDimitry Andric 
246806c3fb27SDimitry Andric   Scope->setName(Union.getName());
246906c3fb27SDimitry Andric   if (Union.hasUniqueName())
247006c3fb27SDimitry Andric     Scope->setLinkageName(Union.getUniqueName());
247106c3fb27SDimitry Andric 
247206c3fb27SDimitry Andric   if (Union.isNested()) {
247306c3fb27SDimitry Andric     Scope->setIsNested();
247406c3fb27SDimitry Andric     createParents(Union.getName(), Scope);
247506c3fb27SDimitry Andric   } else {
247606c3fb27SDimitry Andric     if (LVScope *Namespace = Shared->NamespaceDeduction.get(Union.getName()))
247706c3fb27SDimitry Andric       Namespace->addElement(Scope);
247806c3fb27SDimitry Andric     else
247906c3fb27SDimitry Andric       Reader->getCompileUnit()->addElement(Scope);
248006c3fb27SDimitry Andric   }
248106c3fb27SDimitry Andric 
248206c3fb27SDimitry Andric   if (!Union.getFieldList().isNoneType()) {
248306c3fb27SDimitry Andric     LazyRandomTypeCollection &Types = types();
248406c3fb27SDimitry Andric     // Pass down the TypeIndex 'TI' for the aggregate containing the field list.
248506c3fb27SDimitry Andric     CVType CVFieldList = Types.getType(Union.getFieldList());
248606c3fb27SDimitry Andric     if (Error Err = finishVisitation(CVFieldList, TI, Scope))
248706c3fb27SDimitry Andric       return Err;
248806c3fb27SDimitry Andric   }
248906c3fb27SDimitry Andric 
249006c3fb27SDimitry Andric   return Error::success();
249106c3fb27SDimitry Andric }
249206c3fb27SDimitry Andric 
249306c3fb27SDimitry Andric // LF_TYPESERVER2 (TPI)
visitKnownRecord(CVType & Record,TypeServer2Record & TS,TypeIndex TI,LVElement * Element)249406c3fb27SDimitry Andric Error LVLogicalVisitor::visitKnownRecord(CVType &Record, TypeServer2Record &TS,
249506c3fb27SDimitry Andric                                          TypeIndex TI, LVElement *Element) {
249606c3fb27SDimitry Andric   LLVM_DEBUG({
249706c3fb27SDimitry Andric     printTypeBegin(Record, TI, Element, StreamTPI);
249806c3fb27SDimitry Andric     W.printString("Guid", formatv("{0}", TS.getGuid()).str());
249906c3fb27SDimitry Andric     W.printNumber("Age", TS.getAge());
250006c3fb27SDimitry Andric     W.printString("Name", TS.getName());
250106c3fb27SDimitry Andric     printTypeEnd(Record);
250206c3fb27SDimitry Andric   });
250306c3fb27SDimitry Andric   return Error::success();
250406c3fb27SDimitry Andric }
250506c3fb27SDimitry Andric 
250606c3fb27SDimitry Andric // LF_VFTABLE (TPI)
visitKnownRecord(CVType & Record,VFTableRecord & VFT,TypeIndex TI,LVElement * Element)250706c3fb27SDimitry Andric Error LVLogicalVisitor::visitKnownRecord(CVType &Record, VFTableRecord &VFT,
250806c3fb27SDimitry Andric                                          TypeIndex TI, LVElement *Element) {
250906c3fb27SDimitry Andric   LLVM_DEBUG({
251006c3fb27SDimitry Andric     printTypeBegin(Record, TI, Element, StreamTPI);
251106c3fb27SDimitry Andric     printTypeIndex("CompleteClass", VFT.getCompleteClass(), StreamTPI);
251206c3fb27SDimitry Andric     printTypeIndex("OverriddenVFTable", VFT.getOverriddenVTable(), StreamTPI);
251306c3fb27SDimitry Andric     W.printHex("VFPtrOffset", VFT.getVFPtrOffset());
251406c3fb27SDimitry Andric     W.printString("VFTableName", VFT.getName());
251506c3fb27SDimitry Andric     for (const StringRef &N : VFT.getMethodNames())
251606c3fb27SDimitry Andric       W.printString("MethodName", N);
251706c3fb27SDimitry Andric     printTypeEnd(Record);
251806c3fb27SDimitry Andric   });
251906c3fb27SDimitry Andric   return Error::success();
252006c3fb27SDimitry Andric }
252106c3fb27SDimitry Andric 
252206c3fb27SDimitry Andric // LF_VTSHAPE (TPI)
visitKnownRecord(CVType & Record,VFTableShapeRecord & Shape,TypeIndex TI,LVElement * Element)252306c3fb27SDimitry Andric Error LVLogicalVisitor::visitKnownRecord(CVType &Record,
252406c3fb27SDimitry Andric                                          VFTableShapeRecord &Shape,
252506c3fb27SDimitry Andric                                          TypeIndex TI, LVElement *Element) {
252606c3fb27SDimitry Andric   LLVM_DEBUG({
252706c3fb27SDimitry Andric     printTypeBegin(Record, TI, Element, StreamTPI);
252806c3fb27SDimitry Andric     W.printNumber("VFEntryCount", Shape.getEntryCount());
252906c3fb27SDimitry Andric     printTypeEnd(Record);
253006c3fb27SDimitry Andric   });
253106c3fb27SDimitry Andric   return Error::success();
253206c3fb27SDimitry Andric }
253306c3fb27SDimitry Andric 
253406c3fb27SDimitry Andric // LF_SUBSTR_LIST (TPI)/(IPI)
visitKnownRecord(CVType & Record,StringListRecord & Strings,TypeIndex TI,LVElement * Element)253506c3fb27SDimitry Andric Error LVLogicalVisitor::visitKnownRecord(CVType &Record,
253606c3fb27SDimitry Andric                                          StringListRecord &Strings,
253706c3fb27SDimitry Andric                                          TypeIndex TI, LVElement *Element) {
253806c3fb27SDimitry Andric   // All the indices are references into the TPI/IPI stream.
253906c3fb27SDimitry Andric   LLVM_DEBUG({
254006c3fb27SDimitry Andric     printTypeBegin(Record, TI, Element, StreamIPI);
254106c3fb27SDimitry Andric     ArrayRef<TypeIndex> Indices = Strings.getIndices();
254206c3fb27SDimitry Andric     uint32_t Size = Indices.size();
254306c3fb27SDimitry Andric     W.printNumber("NumStrings", Size);
254406c3fb27SDimitry Andric     ListScope Arguments(W, "Strings");
254506c3fb27SDimitry Andric     for (uint32_t I = 0; I < Size; ++I)
254606c3fb27SDimitry Andric       printTypeIndex("String", Indices[I], StreamIPI);
254706c3fb27SDimitry Andric     printTypeEnd(Record);
254806c3fb27SDimitry Andric   });
254906c3fb27SDimitry Andric   return Error::success();
255006c3fb27SDimitry Andric }
255106c3fb27SDimitry Andric 
255206c3fb27SDimitry Andric // LF_STRING_ID (TPI)/(IPI)
visitKnownRecord(CVType & Record,StringIdRecord & String,TypeIndex TI,LVElement * Element)255306c3fb27SDimitry Andric Error LVLogicalVisitor::visitKnownRecord(CVType &Record, StringIdRecord &String,
255406c3fb27SDimitry Andric                                          TypeIndex TI, LVElement *Element) {
255506c3fb27SDimitry Andric   // All args are references into the TPI/IPI stream.
255606c3fb27SDimitry Andric   LLVM_DEBUG({
255706c3fb27SDimitry Andric     printTypeIndex("\nTI", TI, StreamIPI);
255806c3fb27SDimitry Andric     printTypeIndex("Id", String.getId(), StreamIPI);
255906c3fb27SDimitry Andric     W.printString("StringData", String.getString());
256006c3fb27SDimitry Andric   });
256106c3fb27SDimitry Andric 
256206c3fb27SDimitry Andric   if (LVScope *Namespace = Shared->NamespaceDeduction.get(
256306c3fb27SDimitry Andric           String.getString(), /*CheckScope=*/false)) {
256406c3fb27SDimitry Andric     // The function is already at different scope. In order to reflect
256506c3fb27SDimitry Andric     // the correct parent, move it to the namespace.
256606c3fb27SDimitry Andric     if (LVScope *Scope = Element->getParentScope())
256706c3fb27SDimitry Andric       Scope->removeElement(Element);
256806c3fb27SDimitry Andric     Namespace->addElement(Element);
256906c3fb27SDimitry Andric   }
257006c3fb27SDimitry Andric 
257106c3fb27SDimitry Andric   return Error::success();
257206c3fb27SDimitry Andric }
257306c3fb27SDimitry Andric 
257406c3fb27SDimitry Andric // LF_UDT_SRC_LINE (TPI)/(IPI)
visitKnownRecord(CVType & Record,UdtSourceLineRecord & SourceLine,TypeIndex TI,LVElement * Element)257506c3fb27SDimitry Andric Error LVLogicalVisitor::visitKnownRecord(CVType &Record,
257606c3fb27SDimitry Andric                                          UdtSourceLineRecord &SourceLine,
257706c3fb27SDimitry Andric                                          TypeIndex TI, LVElement *Element) {
257806c3fb27SDimitry Andric   // All args are references into the TPI/IPI stream.
257906c3fb27SDimitry Andric   LLVM_DEBUG({
258006c3fb27SDimitry Andric     printTypeIndex("\nTI", TI, StreamIPI);
258106c3fb27SDimitry Andric     printTypeIndex("UDT", SourceLine.getUDT(), StreamIPI);
258206c3fb27SDimitry Andric     printTypeIndex("SourceFile", SourceLine.getSourceFile(), StreamIPI);
258306c3fb27SDimitry Andric     W.printNumber("LineNumber", SourceLine.getLineNumber());
258406c3fb27SDimitry Andric   });
258506c3fb27SDimitry Andric   return Error::success();
258606c3fb27SDimitry Andric }
258706c3fb27SDimitry Andric 
258806c3fb27SDimitry Andric // LF_UDT_MOD_SRC_LINE (TPI)/(IPI)
visitKnownRecord(CVType & Record,UdtModSourceLineRecord & ModSourceLine,TypeIndex TI,LVElement * Element)258906c3fb27SDimitry Andric Error LVLogicalVisitor::visitKnownRecord(CVType &Record,
259006c3fb27SDimitry Andric                                          UdtModSourceLineRecord &ModSourceLine,
259106c3fb27SDimitry Andric                                          TypeIndex TI, LVElement *Element) {
259206c3fb27SDimitry Andric   // All args are references into the TPI/IPI stream.
259306c3fb27SDimitry Andric   LLVM_DEBUG({
259406c3fb27SDimitry Andric     printTypeBegin(Record, TI, Element, StreamIPI);
259506c3fb27SDimitry Andric     printTypeIndex("\nTI", TI, StreamIPI);
259606c3fb27SDimitry Andric     printTypeIndex("UDT", ModSourceLine.getUDT(), StreamIPI);
259706c3fb27SDimitry Andric     printTypeIndex("SourceFile", ModSourceLine.getSourceFile(), StreamIPI);
259806c3fb27SDimitry Andric     W.printNumber("LineNumber", ModSourceLine.getLineNumber());
259906c3fb27SDimitry Andric     W.printNumber("Module", ModSourceLine.getModule());
260006c3fb27SDimitry Andric     printTypeEnd(Record);
260106c3fb27SDimitry Andric   });
260206c3fb27SDimitry Andric   return Error::success();
260306c3fb27SDimitry Andric }
260406c3fb27SDimitry Andric 
260506c3fb27SDimitry Andric // LF_PRECOMP (TPI)
visitKnownRecord(CVType & Record,PrecompRecord & Precomp,TypeIndex TI,LVElement * Element)260606c3fb27SDimitry Andric Error LVLogicalVisitor::visitKnownRecord(CVType &Record, PrecompRecord &Precomp,
260706c3fb27SDimitry Andric                                          TypeIndex TI, LVElement *Element) {
260806c3fb27SDimitry Andric   LLVM_DEBUG({
260906c3fb27SDimitry Andric     printTypeBegin(Record, TI, Element, StreamTPI);
261006c3fb27SDimitry Andric     W.printHex("StartIndex", Precomp.getStartTypeIndex());
261106c3fb27SDimitry Andric     W.printHex("Count", Precomp.getTypesCount());
261206c3fb27SDimitry Andric     W.printHex("Signature", Precomp.getSignature());
261306c3fb27SDimitry Andric     W.printString("PrecompFile", Precomp.getPrecompFilePath());
261406c3fb27SDimitry Andric     printTypeEnd(Record);
261506c3fb27SDimitry Andric   });
261606c3fb27SDimitry Andric   return Error::success();
261706c3fb27SDimitry Andric }
261806c3fb27SDimitry Andric 
261906c3fb27SDimitry Andric // LF_ENDPRECOMP (TPI)
visitKnownRecord(CVType & Record,EndPrecompRecord & EndPrecomp,TypeIndex TI,LVElement * Element)262006c3fb27SDimitry Andric Error LVLogicalVisitor::visitKnownRecord(CVType &Record,
262106c3fb27SDimitry Andric                                          EndPrecompRecord &EndPrecomp,
262206c3fb27SDimitry Andric                                          TypeIndex TI, LVElement *Element) {
262306c3fb27SDimitry Andric   LLVM_DEBUG({
262406c3fb27SDimitry Andric     printTypeBegin(Record, TI, Element, StreamTPI);
262506c3fb27SDimitry Andric     W.printHex("Signature", EndPrecomp.getSignature());
262606c3fb27SDimitry Andric     printTypeEnd(Record);
262706c3fb27SDimitry Andric   });
262806c3fb27SDimitry Andric   return Error::success();
262906c3fb27SDimitry Andric }
263006c3fb27SDimitry Andric 
visitUnknownMember(CVMemberRecord & Record,TypeIndex TI)263106c3fb27SDimitry Andric Error LVLogicalVisitor::visitUnknownMember(CVMemberRecord &Record,
263206c3fb27SDimitry Andric                                            TypeIndex TI) {
263306c3fb27SDimitry Andric   LLVM_DEBUG({ W.printHex("UnknownMember", unsigned(Record.Kind)); });
263406c3fb27SDimitry Andric   return Error::success();
263506c3fb27SDimitry Andric }
263606c3fb27SDimitry Andric 
263706c3fb27SDimitry Andric // LF_BCLASS, LF_BINTERFACE
visitKnownMember(CVMemberRecord & Record,BaseClassRecord & Base,TypeIndex TI,LVElement * Element)263806c3fb27SDimitry Andric Error LVLogicalVisitor::visitKnownMember(CVMemberRecord &Record,
263906c3fb27SDimitry Andric                                          BaseClassRecord &Base, TypeIndex TI,
264006c3fb27SDimitry Andric                                          LVElement *Element) {
264106c3fb27SDimitry Andric   LLVM_DEBUG({
264206c3fb27SDimitry Andric     printMemberBegin(Record, TI, Element, StreamTPI);
264306c3fb27SDimitry Andric     printTypeIndex("BaseType", Base.getBaseType(), StreamTPI);
264406c3fb27SDimitry Andric     W.printHex("BaseOffset", Base.getBaseOffset());
264506c3fb27SDimitry Andric     printMemberEnd(Record);
264606c3fb27SDimitry Andric   });
264706c3fb27SDimitry Andric 
264806c3fb27SDimitry Andric   createElement(Record.Kind);
264906c3fb27SDimitry Andric   if (LVSymbol *Symbol = CurrentSymbol) {
265006c3fb27SDimitry Andric     LVElement *BaseClass = getElement(StreamTPI, Base.getBaseType());
265106c3fb27SDimitry Andric     Symbol->setName(BaseClass->getName());
265206c3fb27SDimitry Andric     Symbol->setType(BaseClass);
265306c3fb27SDimitry Andric     Symbol->setAccessibilityCode(Base.getAccess());
265406c3fb27SDimitry Andric     static_cast<LVScope *>(Element)->addElement(Symbol);
265506c3fb27SDimitry Andric   }
265606c3fb27SDimitry Andric 
265706c3fb27SDimitry Andric   return Error::success();
265806c3fb27SDimitry Andric }
265906c3fb27SDimitry Andric 
266006c3fb27SDimitry Andric // LF_MEMBER
visitKnownMember(CVMemberRecord & Record,DataMemberRecord & Field,TypeIndex TI,LVElement * Element)266106c3fb27SDimitry Andric Error LVLogicalVisitor::visitKnownMember(CVMemberRecord &Record,
266206c3fb27SDimitry Andric                                          DataMemberRecord &Field, TypeIndex TI,
266306c3fb27SDimitry Andric                                          LVElement *Element) {
266406c3fb27SDimitry Andric   LLVM_DEBUG({
266506c3fb27SDimitry Andric     printMemberBegin(Record, TI, Element, StreamTPI);
266606c3fb27SDimitry Andric     printTypeIndex("Type", Field.getType(), StreamTPI);
266706c3fb27SDimitry Andric     W.printHex("FieldOffset", Field.getFieldOffset());
266806c3fb27SDimitry Andric     W.printString("Name", Field.getName());
266906c3fb27SDimitry Andric     printMemberEnd(Record);
267006c3fb27SDimitry Andric   });
267106c3fb27SDimitry Andric 
267206c3fb27SDimitry Andric   // Create the data member.
267306c3fb27SDimitry Andric   createDataMember(Record, static_cast<LVScope *>(Element), Field.getName(),
267406c3fb27SDimitry Andric                    Field.getType(), Field.getAccess());
267506c3fb27SDimitry Andric   return Error::success();
267606c3fb27SDimitry Andric }
267706c3fb27SDimitry Andric 
267806c3fb27SDimitry Andric // LF_ENUMERATE
visitKnownMember(CVMemberRecord & Record,EnumeratorRecord & Enum,TypeIndex TI,LVElement * Element)267906c3fb27SDimitry Andric Error LVLogicalVisitor::visitKnownMember(CVMemberRecord &Record,
268006c3fb27SDimitry Andric                                          EnumeratorRecord &Enum, TypeIndex TI,
268106c3fb27SDimitry Andric                                          LVElement *Element) {
268206c3fb27SDimitry Andric   LLVM_DEBUG({
268306c3fb27SDimitry Andric     printMemberBegin(Record, TI, Element, StreamTPI);
268406c3fb27SDimitry Andric     W.printNumber("EnumValue", Enum.getValue());
268506c3fb27SDimitry Andric     W.printString("Name", Enum.getName());
268606c3fb27SDimitry Andric     printMemberEnd(Record);
268706c3fb27SDimitry Andric   });
268806c3fb27SDimitry Andric 
268906c3fb27SDimitry Andric   createElement(Record.Kind);
269006c3fb27SDimitry Andric   if (LVType *Type = CurrentType) {
269106c3fb27SDimitry Andric     Type->setName(Enum.getName());
269206c3fb27SDimitry Andric     SmallString<16> Value;
269306c3fb27SDimitry Andric     Enum.getValue().toString(Value, 16, true, true);
269406c3fb27SDimitry Andric     Type->setValue(Value);
269506c3fb27SDimitry Andric     static_cast<LVScope *>(Element)->addElement(CurrentType);
269606c3fb27SDimitry Andric   }
269706c3fb27SDimitry Andric 
269806c3fb27SDimitry Andric   return Error::success();
269906c3fb27SDimitry Andric }
270006c3fb27SDimitry Andric 
270106c3fb27SDimitry Andric // LF_INDEX
visitKnownMember(CVMemberRecord & Record,ListContinuationRecord & Cont,TypeIndex TI,LVElement * Element)270206c3fb27SDimitry Andric Error LVLogicalVisitor::visitKnownMember(CVMemberRecord &Record,
270306c3fb27SDimitry Andric                                          ListContinuationRecord &Cont,
270406c3fb27SDimitry Andric                                          TypeIndex TI, LVElement *Element) {
270506c3fb27SDimitry Andric   LLVM_DEBUG({
270606c3fb27SDimitry Andric     printMemberBegin(Record, TI, Element, StreamTPI);
270706c3fb27SDimitry Andric     printTypeIndex("ContinuationIndex", Cont.getContinuationIndex(), StreamTPI);
270806c3fb27SDimitry Andric     printMemberEnd(Record);
270906c3fb27SDimitry Andric   });
271006c3fb27SDimitry Andric   return Error::success();
271106c3fb27SDimitry Andric }
271206c3fb27SDimitry Andric 
271306c3fb27SDimitry Andric // LF_NESTTYPE
visitKnownMember(CVMemberRecord & Record,NestedTypeRecord & Nested,TypeIndex TI,LVElement * Element)271406c3fb27SDimitry Andric Error LVLogicalVisitor::visitKnownMember(CVMemberRecord &Record,
271506c3fb27SDimitry Andric                                          NestedTypeRecord &Nested, TypeIndex TI,
271606c3fb27SDimitry Andric                                          LVElement *Element) {
271706c3fb27SDimitry Andric   LLVM_DEBUG({
271806c3fb27SDimitry Andric     printMemberBegin(Record, TI, Element, StreamTPI);
271906c3fb27SDimitry Andric     printTypeIndex("Type", Nested.getNestedType(), StreamTPI);
272006c3fb27SDimitry Andric     W.printString("Name", Nested.getName());
272106c3fb27SDimitry Andric     printMemberEnd(Record);
272206c3fb27SDimitry Andric   });
272306c3fb27SDimitry Andric 
272406c3fb27SDimitry Andric   if (LVElement *Typedef = createElement(SymbolKind::S_UDT)) {
272506c3fb27SDimitry Andric     Typedef->setName(Nested.getName());
272606c3fb27SDimitry Andric     LVElement *NestedType = getElement(StreamTPI, Nested.getNestedType());
272706c3fb27SDimitry Andric     Typedef->setType(NestedType);
272806c3fb27SDimitry Andric     LVScope *Scope = static_cast<LVScope *>(Element);
272906c3fb27SDimitry Andric     Scope->addElement(Typedef);
273006c3fb27SDimitry Andric 
273106c3fb27SDimitry Andric     if (NestedType && NestedType->getIsNested()) {
273206c3fb27SDimitry Andric       // 'Element' is an aggregate type that may contains this nested type
273306c3fb27SDimitry Andric       // definition. Used their scoped names, to decide on their relationship.
273406c3fb27SDimitry Andric       StringRef RecordName = getRecordName(types(), TI);
273506c3fb27SDimitry Andric 
273606c3fb27SDimitry Andric       StringRef NestedTypeName = NestedType->getName();
273706c3fb27SDimitry Andric       if (NestedTypeName.size() && RecordName.size()) {
273806c3fb27SDimitry Andric         StringRef OuterComponent;
273906c3fb27SDimitry Andric         std::tie(OuterComponent, std::ignore) =
274006c3fb27SDimitry Andric             getInnerComponent(NestedTypeName);
274106c3fb27SDimitry Andric         // We have an already created nested type. Add it to the current scope
274206c3fb27SDimitry Andric         // and update all its children if any.
274306c3fb27SDimitry Andric         if (OuterComponent.size() && OuterComponent.equals(RecordName)) {
274406c3fb27SDimitry Andric           if (!NestedType->getIsScopedAlready()) {
274506c3fb27SDimitry Andric             Scope->addElement(NestedType);
274606c3fb27SDimitry Andric             NestedType->setIsScopedAlready();
274706c3fb27SDimitry Andric             NestedType->updateLevel(Scope);
274806c3fb27SDimitry Andric           }
274906c3fb27SDimitry Andric           Typedef->resetIncludeInPrint();
275006c3fb27SDimitry Andric         }
275106c3fb27SDimitry Andric       }
275206c3fb27SDimitry Andric     }
275306c3fb27SDimitry Andric   }
275406c3fb27SDimitry Andric 
275506c3fb27SDimitry Andric   return Error::success();
275606c3fb27SDimitry Andric }
275706c3fb27SDimitry Andric 
275806c3fb27SDimitry Andric // LF_ONEMETHOD
visitKnownMember(CVMemberRecord & Record,OneMethodRecord & Method,TypeIndex TI,LVElement * Element)275906c3fb27SDimitry Andric Error LVLogicalVisitor::visitKnownMember(CVMemberRecord &Record,
276006c3fb27SDimitry Andric                                          OneMethodRecord &Method, TypeIndex TI,
276106c3fb27SDimitry Andric                                          LVElement *Element) {
276206c3fb27SDimitry Andric   LLVM_DEBUG({
276306c3fb27SDimitry Andric     printMemberBegin(Record, TI, Element, StreamTPI);
276406c3fb27SDimitry Andric     printTypeIndex("Type", Method.getType(), StreamTPI);
276506c3fb27SDimitry Andric     // If virtual, then read the vftable offset.
276606c3fb27SDimitry Andric     if (Method.isIntroducingVirtual())
276706c3fb27SDimitry Andric       W.printHex("VFTableOffset", Method.getVFTableOffset());
276806c3fb27SDimitry Andric     W.printString("Name", Method.getName());
276906c3fb27SDimitry Andric     printMemberEnd(Record);
277006c3fb27SDimitry Andric   });
277106c3fb27SDimitry Andric 
277206c3fb27SDimitry Andric   // All the LF_ONEMETHOD objects share the same type description.
277306c3fb27SDimitry Andric   // We have to create a scope object for each one and get the required
277406c3fb27SDimitry Andric   // information from the LF_MFUNCTION object.
277506c3fb27SDimitry Andric   ProcessArgumentList = true;
277606c3fb27SDimitry Andric   if (LVElement *MemberFunction = createElement(TypeLeafKind::LF_ONEMETHOD)) {
277706c3fb27SDimitry Andric     MemberFunction->setIsFinalized();
277806c3fb27SDimitry Andric     static_cast<LVScope *>(Element)->addElement(MemberFunction);
277906c3fb27SDimitry Andric 
278006c3fb27SDimitry Andric     MemberFunction->setName(Method.getName());
278106c3fb27SDimitry Andric     MemberFunction->setAccessibilityCode(Method.getAccess());
278206c3fb27SDimitry Andric 
278306c3fb27SDimitry Andric     MethodKind Kind = Method.getMethodKind();
278406c3fb27SDimitry Andric     if (Kind == MethodKind::Static)
278506c3fb27SDimitry Andric       MemberFunction->setIsStatic();
278606c3fb27SDimitry Andric     MemberFunction->setVirtualityCode(Kind);
278706c3fb27SDimitry Andric 
278806c3fb27SDimitry Andric     MethodOptions Flags = Method.Attrs.getFlags();
278906c3fb27SDimitry Andric     if (MethodOptions::CompilerGenerated ==
279006c3fb27SDimitry Andric         (Flags & MethodOptions::CompilerGenerated))
279106c3fb27SDimitry Andric       MemberFunction->setIsArtificial();
279206c3fb27SDimitry Andric 
279306c3fb27SDimitry Andric     LazyRandomTypeCollection &Types = types();
279406c3fb27SDimitry Andric     CVType CVMethodType = Types.getType(Method.getType());
279506c3fb27SDimitry Andric     if (Error Err =
279606c3fb27SDimitry Andric             finishVisitation(CVMethodType, Method.getType(), MemberFunction))
279706c3fb27SDimitry Andric       return Err;
279806c3fb27SDimitry Andric   }
279906c3fb27SDimitry Andric   ProcessArgumentList = false;
280006c3fb27SDimitry Andric 
280106c3fb27SDimitry Andric   return Error::success();
280206c3fb27SDimitry Andric }
280306c3fb27SDimitry Andric 
280406c3fb27SDimitry Andric // LF_METHOD
visitKnownMember(CVMemberRecord & Record,OverloadedMethodRecord & Method,TypeIndex TI,LVElement * Element)280506c3fb27SDimitry Andric Error LVLogicalVisitor::visitKnownMember(CVMemberRecord &Record,
280606c3fb27SDimitry Andric                                          OverloadedMethodRecord &Method,
280706c3fb27SDimitry Andric                                          TypeIndex TI, LVElement *Element) {
280806c3fb27SDimitry Andric   LLVM_DEBUG({
280906c3fb27SDimitry Andric     printMemberBegin(Record, TI, Element, StreamTPI);
281006c3fb27SDimitry Andric     W.printHex("MethodCount", Method.getNumOverloads());
281106c3fb27SDimitry Andric     printTypeIndex("MethodListIndex", Method.getMethodList(), StreamTPI);
281206c3fb27SDimitry Andric     W.printString("Name", Method.getName());
281306c3fb27SDimitry Andric     printMemberEnd(Record);
281406c3fb27SDimitry Andric   });
281506c3fb27SDimitry Andric 
281606c3fb27SDimitry Andric   // Record the overloaded method name, which will be used during the
281706c3fb27SDimitry Andric   // traversal of the method list.
281806c3fb27SDimitry Andric   LazyRandomTypeCollection &Types = types();
281906c3fb27SDimitry Andric   OverloadedMethodName = Method.getName();
282006c3fb27SDimitry Andric   CVType CVMethods = Types.getType(Method.getMethodList());
282106c3fb27SDimitry Andric   if (Error Err = finishVisitation(CVMethods, Method.getMethodList(), Element))
282206c3fb27SDimitry Andric     return Err;
282306c3fb27SDimitry Andric 
282406c3fb27SDimitry Andric   return Error::success();
282506c3fb27SDimitry Andric }
282606c3fb27SDimitry Andric 
282706c3fb27SDimitry Andric // LF_STMEMBER
visitKnownMember(CVMemberRecord & Record,StaticDataMemberRecord & Field,TypeIndex TI,LVElement * Element)282806c3fb27SDimitry Andric Error LVLogicalVisitor::visitKnownMember(CVMemberRecord &Record,
282906c3fb27SDimitry Andric                                          StaticDataMemberRecord &Field,
283006c3fb27SDimitry Andric                                          TypeIndex TI, LVElement *Element) {
283106c3fb27SDimitry Andric   LLVM_DEBUG({
283206c3fb27SDimitry Andric     printMemberBegin(Record, TI, Element, StreamTPI);
283306c3fb27SDimitry Andric     printTypeIndex("Type", Field.getType(), StreamTPI);
283406c3fb27SDimitry Andric     W.printString("Name", Field.getName());
283506c3fb27SDimitry Andric     printMemberEnd(Record);
283606c3fb27SDimitry Andric   });
283706c3fb27SDimitry Andric 
283806c3fb27SDimitry Andric   // Create the data member.
283906c3fb27SDimitry Andric   createDataMember(Record, static_cast<LVScope *>(Element), Field.getName(),
284006c3fb27SDimitry Andric                    Field.getType(), Field.getAccess());
284106c3fb27SDimitry Andric   return Error::success();
284206c3fb27SDimitry Andric }
284306c3fb27SDimitry Andric 
284406c3fb27SDimitry Andric // LF_VFUNCTAB
visitKnownMember(CVMemberRecord & Record,VFPtrRecord & VFTable,TypeIndex TI,LVElement * Element)284506c3fb27SDimitry Andric Error LVLogicalVisitor::visitKnownMember(CVMemberRecord &Record,
284606c3fb27SDimitry Andric                                          VFPtrRecord &VFTable, TypeIndex TI,
284706c3fb27SDimitry Andric                                          LVElement *Element) {
284806c3fb27SDimitry Andric   LLVM_DEBUG({
284906c3fb27SDimitry Andric     printMemberBegin(Record, TI, Element, StreamTPI);
285006c3fb27SDimitry Andric     printTypeIndex("Type", VFTable.getType(), StreamTPI);
285106c3fb27SDimitry Andric     printMemberEnd(Record);
285206c3fb27SDimitry Andric   });
285306c3fb27SDimitry Andric   return Error::success();
285406c3fb27SDimitry Andric }
285506c3fb27SDimitry Andric 
285606c3fb27SDimitry Andric // LF_VBCLASS, LF_IVBCLASS
visitKnownMember(CVMemberRecord & Record,VirtualBaseClassRecord & Base,TypeIndex TI,LVElement * Element)285706c3fb27SDimitry Andric Error LVLogicalVisitor::visitKnownMember(CVMemberRecord &Record,
285806c3fb27SDimitry Andric                                          VirtualBaseClassRecord &Base,
285906c3fb27SDimitry Andric                                          TypeIndex TI, LVElement *Element) {
286006c3fb27SDimitry Andric   LLVM_DEBUG({
286106c3fb27SDimitry Andric     printMemberBegin(Record, TI, Element, StreamTPI);
286206c3fb27SDimitry Andric     printTypeIndex("BaseType", Base.getBaseType(), StreamTPI);
286306c3fb27SDimitry Andric     printTypeIndex("VBPtrType", Base.getVBPtrType(), StreamTPI);
286406c3fb27SDimitry Andric     W.printHex("VBPtrOffset", Base.getVBPtrOffset());
286506c3fb27SDimitry Andric     W.printHex("VBTableIndex", Base.getVTableIndex());
286606c3fb27SDimitry Andric     printMemberEnd(Record);
286706c3fb27SDimitry Andric   });
286806c3fb27SDimitry Andric 
286906c3fb27SDimitry Andric   createElement(Record.Kind);
287006c3fb27SDimitry Andric   if (LVSymbol *Symbol = CurrentSymbol) {
287106c3fb27SDimitry Andric     LVElement *BaseClass = getElement(StreamTPI, Base.getBaseType());
287206c3fb27SDimitry Andric     Symbol->setName(BaseClass->getName());
287306c3fb27SDimitry Andric     Symbol->setType(BaseClass);
287406c3fb27SDimitry Andric     Symbol->setAccessibilityCode(Base.getAccess());
287506c3fb27SDimitry Andric     Symbol->setVirtualityCode(MethodKind::Virtual);
287606c3fb27SDimitry Andric     static_cast<LVScope *>(Element)->addElement(Symbol);
287706c3fb27SDimitry Andric   }
287806c3fb27SDimitry Andric 
287906c3fb27SDimitry Andric   return Error::success();
288006c3fb27SDimitry Andric }
288106c3fb27SDimitry Andric 
visitMemberRecord(CVMemberRecord & Record,TypeVisitorCallbacks & Callbacks,TypeIndex TI,LVElement * Element)288206c3fb27SDimitry Andric Error LVLogicalVisitor::visitMemberRecord(CVMemberRecord &Record,
288306c3fb27SDimitry Andric                                           TypeVisitorCallbacks &Callbacks,
288406c3fb27SDimitry Andric                                           TypeIndex TI, LVElement *Element) {
288506c3fb27SDimitry Andric   if (Error Err = Callbacks.visitMemberBegin(Record))
288606c3fb27SDimitry Andric     return Err;
288706c3fb27SDimitry Andric 
288806c3fb27SDimitry Andric   switch (Record.Kind) {
288906c3fb27SDimitry Andric   default:
289006c3fb27SDimitry Andric     if (Error Err = Callbacks.visitUnknownMember(Record))
289106c3fb27SDimitry Andric       return Err;
289206c3fb27SDimitry Andric     break;
289306c3fb27SDimitry Andric #define MEMBER_RECORD(EnumName, EnumVal, Name)                                 \
289406c3fb27SDimitry Andric   case EnumName: {                                                             \
289506c3fb27SDimitry Andric     if (Error Err =                                                            \
289606c3fb27SDimitry Andric             visitKnownMember<Name##Record>(Record, Callbacks, TI, Element))    \
289706c3fb27SDimitry Andric       return Err;                                                              \
289806c3fb27SDimitry Andric     break;                                                                     \
289906c3fb27SDimitry Andric   }
290006c3fb27SDimitry Andric #define MEMBER_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName)                \
290106c3fb27SDimitry Andric   MEMBER_RECORD(EnumVal, EnumVal, AliasName)
290206c3fb27SDimitry Andric #define TYPE_RECORD(EnumName, EnumVal, Name)
290306c3fb27SDimitry Andric #define TYPE_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName)
290406c3fb27SDimitry Andric #include "llvm/DebugInfo/CodeView/CodeViewTypes.def"
290506c3fb27SDimitry Andric   }
290606c3fb27SDimitry Andric 
290706c3fb27SDimitry Andric   if (Error Err = Callbacks.visitMemberEnd(Record))
290806c3fb27SDimitry Andric     return Err;
290906c3fb27SDimitry Andric 
291006c3fb27SDimitry Andric   return Error::success();
291106c3fb27SDimitry Andric }
291206c3fb27SDimitry Andric 
finishVisitation(CVType & Record,TypeIndex TI,LVElement * Element)291306c3fb27SDimitry Andric Error LVLogicalVisitor::finishVisitation(CVType &Record, TypeIndex TI,
291406c3fb27SDimitry Andric                                          LVElement *Element) {
291506c3fb27SDimitry Andric   switch (Record.kind()) {
291606c3fb27SDimitry Andric   default:
291706c3fb27SDimitry Andric     if (Error Err = visitUnknownType(Record, TI))
291806c3fb27SDimitry Andric       return Err;
291906c3fb27SDimitry Andric     break;
292006c3fb27SDimitry Andric #define TYPE_RECORD(EnumName, EnumVal, Name)                                   \
292106c3fb27SDimitry Andric   case EnumName: {                                                             \
292206c3fb27SDimitry Andric     if (Error Err = visitKnownRecord<Name##Record>(Record, TI, Element))       \
292306c3fb27SDimitry Andric       return Err;                                                              \
292406c3fb27SDimitry Andric     break;                                                                     \
292506c3fb27SDimitry Andric   }
292606c3fb27SDimitry Andric #define TYPE_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName)                  \
292706c3fb27SDimitry Andric   TYPE_RECORD(EnumVal, EnumVal, AliasName)
292806c3fb27SDimitry Andric #define MEMBER_RECORD(EnumName, EnumVal, Name)
292906c3fb27SDimitry Andric #define MEMBER_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName)
293006c3fb27SDimitry Andric #include "llvm/DebugInfo/CodeView/CodeViewTypes.def"
293106c3fb27SDimitry Andric   }
293206c3fb27SDimitry Andric 
293306c3fb27SDimitry Andric   return Error::success();
293406c3fb27SDimitry Andric }
293506c3fb27SDimitry Andric 
293606c3fb27SDimitry Andric // Customized version of 'FieldListVisitHelper'.
visitFieldListMemberStream(TypeIndex TI,LVElement * Element,ArrayRef<uint8_t> FieldList)293706c3fb27SDimitry Andric Error LVLogicalVisitor::visitFieldListMemberStream(
293806c3fb27SDimitry Andric     TypeIndex TI, LVElement *Element, ArrayRef<uint8_t> FieldList) {
2939*5f757f3fSDimitry Andric   BinaryByteStream Stream(FieldList, llvm::endianness::little);
294006c3fb27SDimitry Andric   BinaryStreamReader Reader(Stream);
294106c3fb27SDimitry Andric   FieldListDeserializer Deserializer(Reader);
294206c3fb27SDimitry Andric   TypeVisitorCallbackPipeline Pipeline;
294306c3fb27SDimitry Andric   Pipeline.addCallbackToPipeline(Deserializer);
294406c3fb27SDimitry Andric 
294506c3fb27SDimitry Andric   TypeLeafKind Leaf;
294606c3fb27SDimitry Andric   while (!Reader.empty()) {
294706c3fb27SDimitry Andric     if (Error Err = Reader.readEnum(Leaf))
294806c3fb27SDimitry Andric       return Err;
294906c3fb27SDimitry Andric 
295006c3fb27SDimitry Andric     CVMemberRecord Record;
295106c3fb27SDimitry Andric     Record.Kind = Leaf;
295206c3fb27SDimitry Andric     if (Error Err = visitMemberRecord(Record, Pipeline, TI, Element))
295306c3fb27SDimitry Andric       return Err;
295406c3fb27SDimitry Andric   }
295506c3fb27SDimitry Andric 
295606c3fb27SDimitry Andric   return Error::success();
295706c3fb27SDimitry Andric }
295806c3fb27SDimitry Andric 
addElement(LVScope * Scope,bool IsCompileUnit)295906c3fb27SDimitry Andric void LVLogicalVisitor::addElement(LVScope *Scope, bool IsCompileUnit) {
296006c3fb27SDimitry Andric   // The CodeView specifications does not treat S_COMPILE2 and S_COMPILE3
296106c3fb27SDimitry Andric   // as symbols that open a scope. The CodeView reader, treat them in a
296206c3fb27SDimitry Andric   // similar way as DWARF. As there is no a symbole S_END to close the
296306c3fb27SDimitry Andric   // compile unit, we need to check for the next compile unit.
296406c3fb27SDimitry Andric   if (IsCompileUnit) {
296506c3fb27SDimitry Andric     if (!ScopeStack.empty())
296606c3fb27SDimitry Andric       popScope();
296706c3fb27SDimitry Andric     InCompileUnitScope = true;
296806c3fb27SDimitry Andric   }
296906c3fb27SDimitry Andric 
297006c3fb27SDimitry Andric   pushScope(Scope);
297106c3fb27SDimitry Andric   ReaderParent->addElement(Scope);
297206c3fb27SDimitry Andric }
297306c3fb27SDimitry Andric 
addElement(LVSymbol * Symbol)297406c3fb27SDimitry Andric void LVLogicalVisitor::addElement(LVSymbol *Symbol) {
297506c3fb27SDimitry Andric   ReaderScope->addElement(Symbol);
297606c3fb27SDimitry Andric }
297706c3fb27SDimitry Andric 
addElement(LVType * Type)297806c3fb27SDimitry Andric void LVLogicalVisitor::addElement(LVType *Type) {
297906c3fb27SDimitry Andric   ReaderScope->addElement(Type);
298006c3fb27SDimitry Andric }
298106c3fb27SDimitry Andric 
createElement(TypeLeafKind Kind)298206c3fb27SDimitry Andric LVElement *LVLogicalVisitor::createElement(TypeLeafKind Kind) {
298306c3fb27SDimitry Andric   CurrentScope = nullptr;
298406c3fb27SDimitry Andric   CurrentSymbol = nullptr;
298506c3fb27SDimitry Andric   CurrentType = nullptr;
298606c3fb27SDimitry Andric 
298706c3fb27SDimitry Andric   if (Kind < TypeIndex::FirstNonSimpleIndex) {
298806c3fb27SDimitry Andric     CurrentType = Reader->createType();
298906c3fb27SDimitry Andric     CurrentType->setIsBase();
299006c3fb27SDimitry Andric     CurrentType->setTag(dwarf::DW_TAG_base_type);
299106c3fb27SDimitry Andric     if (options().getAttributeBase())
299206c3fb27SDimitry Andric       CurrentType->setIncludeInPrint();
299306c3fb27SDimitry Andric     return CurrentType;
299406c3fb27SDimitry Andric   }
299506c3fb27SDimitry Andric 
299606c3fb27SDimitry Andric   switch (Kind) {
299706c3fb27SDimitry Andric   // Types.
299806c3fb27SDimitry Andric   case TypeLeafKind::LF_ENUMERATE:
299906c3fb27SDimitry Andric     CurrentType = Reader->createTypeEnumerator();
300006c3fb27SDimitry Andric     CurrentType->setTag(dwarf::DW_TAG_enumerator);
300106c3fb27SDimitry Andric     return CurrentType;
300206c3fb27SDimitry Andric   case TypeLeafKind::LF_MODIFIER:
300306c3fb27SDimitry Andric     CurrentType = Reader->createType();
300406c3fb27SDimitry Andric     CurrentType->setIsModifier();
300506c3fb27SDimitry Andric     return CurrentType;
300606c3fb27SDimitry Andric   case TypeLeafKind::LF_POINTER:
300706c3fb27SDimitry Andric     CurrentType = Reader->createType();
300806c3fb27SDimitry Andric     CurrentType->setIsPointer();
300906c3fb27SDimitry Andric     CurrentType->setName("*");
301006c3fb27SDimitry Andric     CurrentType->setTag(dwarf::DW_TAG_pointer_type);
301106c3fb27SDimitry Andric     return CurrentType;
301206c3fb27SDimitry Andric 
301306c3fb27SDimitry Andric     // Symbols.
301406c3fb27SDimitry Andric   case TypeLeafKind::LF_BCLASS:
301506c3fb27SDimitry Andric   case TypeLeafKind::LF_IVBCLASS:
301606c3fb27SDimitry Andric   case TypeLeafKind::LF_VBCLASS:
301706c3fb27SDimitry Andric     CurrentSymbol = Reader->createSymbol();
301806c3fb27SDimitry Andric     CurrentSymbol->setTag(dwarf::DW_TAG_inheritance);
301906c3fb27SDimitry Andric     CurrentSymbol->setIsInheritance();
302006c3fb27SDimitry Andric     return CurrentSymbol;
302106c3fb27SDimitry Andric   case TypeLeafKind::LF_MEMBER:
302206c3fb27SDimitry Andric   case TypeLeafKind::LF_STMEMBER:
302306c3fb27SDimitry Andric     CurrentSymbol = Reader->createSymbol();
302406c3fb27SDimitry Andric     CurrentSymbol->setIsMember();
302506c3fb27SDimitry Andric     CurrentSymbol->setTag(dwarf::DW_TAG_member);
302606c3fb27SDimitry Andric     return CurrentSymbol;
302706c3fb27SDimitry Andric 
302806c3fb27SDimitry Andric   // Scopes.
302906c3fb27SDimitry Andric   case TypeLeafKind::LF_ARRAY:
303006c3fb27SDimitry Andric     CurrentScope = Reader->createScopeArray();
303106c3fb27SDimitry Andric     CurrentScope->setTag(dwarf::DW_TAG_array_type);
303206c3fb27SDimitry Andric     return CurrentScope;
303306c3fb27SDimitry Andric   case TypeLeafKind::LF_CLASS:
303406c3fb27SDimitry Andric     CurrentScope = Reader->createScopeAggregate();
303506c3fb27SDimitry Andric     CurrentScope->setTag(dwarf::DW_TAG_class_type);
303606c3fb27SDimitry Andric     CurrentScope->setIsClass();
303706c3fb27SDimitry Andric     return CurrentScope;
303806c3fb27SDimitry Andric   case TypeLeafKind::LF_ENUM:
303906c3fb27SDimitry Andric     CurrentScope = Reader->createScopeEnumeration();
304006c3fb27SDimitry Andric     CurrentScope->setTag(dwarf::DW_TAG_enumeration_type);
304106c3fb27SDimitry Andric     return CurrentScope;
304206c3fb27SDimitry Andric   case TypeLeafKind::LF_METHOD:
304306c3fb27SDimitry Andric   case TypeLeafKind::LF_ONEMETHOD:
304406c3fb27SDimitry Andric   case TypeLeafKind::LF_PROCEDURE:
304506c3fb27SDimitry Andric     CurrentScope = Reader->createScopeFunction();
304606c3fb27SDimitry Andric     CurrentScope->setIsSubprogram();
304706c3fb27SDimitry Andric     CurrentScope->setTag(dwarf::DW_TAG_subprogram);
304806c3fb27SDimitry Andric     return CurrentScope;
304906c3fb27SDimitry Andric   case TypeLeafKind::LF_STRUCTURE:
305006c3fb27SDimitry Andric     CurrentScope = Reader->createScopeAggregate();
305106c3fb27SDimitry Andric     CurrentScope->setIsStructure();
305206c3fb27SDimitry Andric     CurrentScope->setTag(dwarf::DW_TAG_structure_type);
305306c3fb27SDimitry Andric     return CurrentScope;
305406c3fb27SDimitry Andric   case TypeLeafKind::LF_UNION:
305506c3fb27SDimitry Andric     CurrentScope = Reader->createScopeAggregate();
305606c3fb27SDimitry Andric     CurrentScope->setIsUnion();
305706c3fb27SDimitry Andric     CurrentScope->setTag(dwarf::DW_TAG_union_type);
305806c3fb27SDimitry Andric     return CurrentScope;
305906c3fb27SDimitry Andric   default:
306006c3fb27SDimitry Andric     // If '--internal=tag' and '--print=warning' are specified in the command
306106c3fb27SDimitry Andric     // line, we record and print each seen 'TypeLeafKind'.
306206c3fb27SDimitry Andric     break;
306306c3fb27SDimitry Andric   }
306406c3fb27SDimitry Andric   return nullptr;
306506c3fb27SDimitry Andric }
306606c3fb27SDimitry Andric 
createElement(SymbolKind Kind)306706c3fb27SDimitry Andric LVElement *LVLogicalVisitor::createElement(SymbolKind Kind) {
306806c3fb27SDimitry Andric   CurrentScope = nullptr;
306906c3fb27SDimitry Andric   CurrentSymbol = nullptr;
307006c3fb27SDimitry Andric   CurrentType = nullptr;
307106c3fb27SDimitry Andric   switch (Kind) {
307206c3fb27SDimitry Andric   // Types.
307306c3fb27SDimitry Andric   case SymbolKind::S_UDT:
307406c3fb27SDimitry Andric     CurrentType = Reader->createTypeDefinition();
307506c3fb27SDimitry Andric     CurrentType->setTag(dwarf::DW_TAG_typedef);
307606c3fb27SDimitry Andric     return CurrentType;
307706c3fb27SDimitry Andric 
307806c3fb27SDimitry Andric   // Symbols.
307906c3fb27SDimitry Andric   case SymbolKind::S_CONSTANT:
308006c3fb27SDimitry Andric     CurrentSymbol = Reader->createSymbol();
308106c3fb27SDimitry Andric     CurrentSymbol->setIsConstant();
308206c3fb27SDimitry Andric     CurrentSymbol->setTag(dwarf::DW_TAG_constant);
308306c3fb27SDimitry Andric     return CurrentSymbol;
308406c3fb27SDimitry Andric 
308506c3fb27SDimitry Andric   case SymbolKind::S_BPREL32:
308606c3fb27SDimitry Andric   case SymbolKind::S_REGREL32:
308706c3fb27SDimitry Andric   case SymbolKind::S_GDATA32:
308806c3fb27SDimitry Andric   case SymbolKind::S_LDATA32:
308906c3fb27SDimitry Andric   case SymbolKind::S_LOCAL:
309006c3fb27SDimitry Andric     // During the symbol traversal more information is available to
309106c3fb27SDimitry Andric     // determine if the symbol is a parameter or a variable. At this
309206c3fb27SDimitry Andric     // stage mark it as variable.
309306c3fb27SDimitry Andric     CurrentSymbol = Reader->createSymbol();
309406c3fb27SDimitry Andric     CurrentSymbol->setIsVariable();
309506c3fb27SDimitry Andric     CurrentSymbol->setTag(dwarf::DW_TAG_variable);
309606c3fb27SDimitry Andric     return CurrentSymbol;
309706c3fb27SDimitry Andric 
309806c3fb27SDimitry Andric   // Scopes.
309906c3fb27SDimitry Andric   case SymbolKind::S_BLOCK32:
310006c3fb27SDimitry Andric     CurrentScope = Reader->createScope();
310106c3fb27SDimitry Andric     CurrentScope->setIsLexicalBlock();
310206c3fb27SDimitry Andric     CurrentScope->setTag(dwarf::DW_TAG_lexical_block);
310306c3fb27SDimitry Andric     return CurrentScope;
310406c3fb27SDimitry Andric   case SymbolKind::S_COMPILE2:
310506c3fb27SDimitry Andric   case SymbolKind::S_COMPILE3:
310606c3fb27SDimitry Andric     CurrentScope = Reader->createScopeCompileUnit();
310706c3fb27SDimitry Andric     CurrentScope->setTag(dwarf::DW_TAG_compile_unit);
310806c3fb27SDimitry Andric     Reader->setCompileUnit(static_cast<LVScopeCompileUnit *>(CurrentScope));
310906c3fb27SDimitry Andric     return CurrentScope;
311006c3fb27SDimitry Andric   case SymbolKind::S_INLINESITE:
311106c3fb27SDimitry Andric   case SymbolKind::S_INLINESITE2:
311206c3fb27SDimitry Andric     CurrentScope = Reader->createScopeFunctionInlined();
311306c3fb27SDimitry Andric     CurrentScope->setIsInlinedFunction();
311406c3fb27SDimitry Andric     CurrentScope->setTag(dwarf::DW_TAG_inlined_subroutine);
311506c3fb27SDimitry Andric     return CurrentScope;
311606c3fb27SDimitry Andric   case SymbolKind::S_LPROC32:
311706c3fb27SDimitry Andric   case SymbolKind::S_GPROC32:
311806c3fb27SDimitry Andric   case SymbolKind::S_LPROC32_ID:
311906c3fb27SDimitry Andric   case SymbolKind::S_GPROC32_ID:
312006c3fb27SDimitry Andric   case SymbolKind::S_SEPCODE:
312106c3fb27SDimitry Andric   case SymbolKind::S_THUNK32:
312206c3fb27SDimitry Andric     CurrentScope = Reader->createScopeFunction();
312306c3fb27SDimitry Andric     CurrentScope->setIsSubprogram();
312406c3fb27SDimitry Andric     CurrentScope->setTag(dwarf::DW_TAG_subprogram);
312506c3fb27SDimitry Andric     return CurrentScope;
312606c3fb27SDimitry Andric   default:
312706c3fb27SDimitry Andric     // If '--internal=tag' and '--print=warning' are specified in the command
312806c3fb27SDimitry Andric     // line, we record and print each seen 'SymbolKind'.
312906c3fb27SDimitry Andric     break;
313006c3fb27SDimitry Andric   }
313106c3fb27SDimitry Andric   return nullptr;
313206c3fb27SDimitry Andric }
313306c3fb27SDimitry Andric 
createElement(TypeIndex TI,TypeLeafKind Kind)313406c3fb27SDimitry Andric LVElement *LVLogicalVisitor::createElement(TypeIndex TI, TypeLeafKind Kind) {
313506c3fb27SDimitry Andric   LVElement *Element = Shared->TypeRecords.find(StreamTPI, TI);
313606c3fb27SDimitry Andric   if (!Element) {
313706c3fb27SDimitry Andric     // We are dealing with a base type or pointer to a base type, which are
313806c3fb27SDimitry Andric     // not included explicitly in the CodeView format.
313906c3fb27SDimitry Andric     if (Kind < TypeIndex::FirstNonSimpleIndex) {
314006c3fb27SDimitry Andric       Element = createElement(Kind);
314106c3fb27SDimitry Andric       Element->setIsFinalized();
314206c3fb27SDimitry Andric       Shared->TypeRecords.add(StreamTPI, (TypeIndex)Kind, Kind, Element);
314306c3fb27SDimitry Andric       Element->setOffset(Kind);
314406c3fb27SDimitry Andric       return Element;
314506c3fb27SDimitry Andric     }
314606c3fb27SDimitry Andric     // We are dealing with a pointer to a base type.
314706c3fb27SDimitry Andric     if (TI.getIndex() < TypeIndex::FirstNonSimpleIndex) {
314806c3fb27SDimitry Andric       Element = createElement(Kind);
314906c3fb27SDimitry Andric       Shared->TypeRecords.add(StreamTPI, TI, Kind, Element);
315006c3fb27SDimitry Andric       Element->setOffset(TI.getIndex());
315106c3fb27SDimitry Andric       Element->setOffsetFromTypeIndex();
315206c3fb27SDimitry Andric       return Element;
315306c3fb27SDimitry Andric     }
315406c3fb27SDimitry Andric 
315506c3fb27SDimitry Andric     W.printString("** Not implemented. **");
315606c3fb27SDimitry Andric     printTypeIndex("TypeIndex", TI, StreamTPI);
315706c3fb27SDimitry Andric     W.printString("TypeLeafKind", formatTypeLeafKind(Kind));
315806c3fb27SDimitry Andric     return nullptr;
315906c3fb27SDimitry Andric   }
316006c3fb27SDimitry Andric 
316106c3fb27SDimitry Andric   Element->setOffset(TI.getIndex());
316206c3fb27SDimitry Andric   Element->setOffsetFromTypeIndex();
316306c3fb27SDimitry Andric   return Element;
316406c3fb27SDimitry Andric }
316506c3fb27SDimitry Andric 
createDataMember(CVMemberRecord & Record,LVScope * Parent,StringRef Name,TypeIndex TI,MemberAccess Access)316606c3fb27SDimitry Andric void LVLogicalVisitor::createDataMember(CVMemberRecord &Record, LVScope *Parent,
316706c3fb27SDimitry Andric                                         StringRef Name, TypeIndex TI,
316806c3fb27SDimitry Andric                                         MemberAccess Access) {
316906c3fb27SDimitry Andric   LLVM_DEBUG({
317006c3fb27SDimitry Andric     printTypeIndex("TypeIndex", TI, StreamTPI);
317106c3fb27SDimitry Andric     W.printString("TypeName", Name);
317206c3fb27SDimitry Andric   });
317306c3fb27SDimitry Andric 
317406c3fb27SDimitry Andric   createElement(Record.Kind);
317506c3fb27SDimitry Andric   if (LVSymbol *Symbol = CurrentSymbol) {
317606c3fb27SDimitry Andric     Symbol->setName(Name);
317706c3fb27SDimitry Andric     if (TI.isNoneType() || TI.isSimple())
317806c3fb27SDimitry Andric       Symbol->setType(getElement(StreamTPI, TI));
317906c3fb27SDimitry Andric     else {
318006c3fb27SDimitry Andric       LazyRandomTypeCollection &Types = types();
318106c3fb27SDimitry Andric       CVType CVMemberType = Types.getType(TI);
318206c3fb27SDimitry Andric       if (CVMemberType.kind() == LF_BITFIELD) {
318306c3fb27SDimitry Andric         if (Error Err = finishVisitation(CVMemberType, TI, Symbol)) {
318406c3fb27SDimitry Andric           consumeError(std::move(Err));
318506c3fb27SDimitry Andric           return;
318606c3fb27SDimitry Andric         }
318706c3fb27SDimitry Andric       } else
318806c3fb27SDimitry Andric         Symbol->setType(getElement(StreamTPI, TI));
318906c3fb27SDimitry Andric     }
319006c3fb27SDimitry Andric     Symbol->setAccessibilityCode(Access);
319106c3fb27SDimitry Andric     Parent->addElement(Symbol);
319206c3fb27SDimitry Andric   }
319306c3fb27SDimitry Andric }
319406c3fb27SDimitry Andric 
createParameter(LVElement * Element,StringRef Name,LVScope * Parent)319506c3fb27SDimitry Andric LVSymbol *LVLogicalVisitor::createParameter(LVElement *Element, StringRef Name,
319606c3fb27SDimitry Andric                                             LVScope *Parent) {
319706c3fb27SDimitry Andric   LVSymbol *Parameter = Reader->createSymbol();
319806c3fb27SDimitry Andric   Parent->addElement(Parameter);
319906c3fb27SDimitry Andric   Parameter->setIsParameter();
320006c3fb27SDimitry Andric   Parameter->setTag(dwarf::DW_TAG_formal_parameter);
320106c3fb27SDimitry Andric   Parameter->setName(Name);
320206c3fb27SDimitry Andric   Parameter->setType(Element);
320306c3fb27SDimitry Andric   return Parameter;
320406c3fb27SDimitry Andric }
320506c3fb27SDimitry Andric 
createParameter(TypeIndex TI,StringRef Name,LVScope * Parent)320606c3fb27SDimitry Andric LVSymbol *LVLogicalVisitor::createParameter(TypeIndex TI, StringRef Name,
320706c3fb27SDimitry Andric                                             LVScope *Parent) {
320806c3fb27SDimitry Andric   return createParameter(getElement(StreamTPI, TI), Name, Parent);
320906c3fb27SDimitry Andric }
321006c3fb27SDimitry Andric 
createBaseType(TypeIndex TI,StringRef TypeName)321106c3fb27SDimitry Andric LVType *LVLogicalVisitor::createBaseType(TypeIndex TI, StringRef TypeName) {
321206c3fb27SDimitry Andric   TypeLeafKind SimpleKind = (TypeLeafKind)TI.getSimpleKind();
321306c3fb27SDimitry Andric   TypeIndex TIR = (TypeIndex)SimpleKind;
321406c3fb27SDimitry Andric   LLVM_DEBUG({
321506c3fb27SDimitry Andric     printTypeIndex("TypeIndex", TIR, StreamTPI);
321606c3fb27SDimitry Andric     W.printString("TypeName", TypeName);
321706c3fb27SDimitry Andric   });
321806c3fb27SDimitry Andric 
321906c3fb27SDimitry Andric   if (LVElement *Element = Shared->TypeRecords.find(StreamTPI, TIR))
322006c3fb27SDimitry Andric     return static_cast<LVType *>(Element);
322106c3fb27SDimitry Andric 
322206c3fb27SDimitry Andric   if (createElement(TIR, SimpleKind)) {
322306c3fb27SDimitry Andric     CurrentType->setName(TypeName);
322406c3fb27SDimitry Andric     Reader->getCompileUnit()->addElement(CurrentType);
322506c3fb27SDimitry Andric   }
322606c3fb27SDimitry Andric   return CurrentType;
322706c3fb27SDimitry Andric }
322806c3fb27SDimitry Andric 
createPointerType(TypeIndex TI,StringRef TypeName)322906c3fb27SDimitry Andric LVType *LVLogicalVisitor::createPointerType(TypeIndex TI, StringRef TypeName) {
323006c3fb27SDimitry Andric   LLVM_DEBUG({
323106c3fb27SDimitry Andric     printTypeIndex("TypeIndex", TI, StreamTPI);
323206c3fb27SDimitry Andric     W.printString("TypeName", TypeName);
323306c3fb27SDimitry Andric   });
323406c3fb27SDimitry Andric 
323506c3fb27SDimitry Andric   if (LVElement *Element = Shared->TypeRecords.find(StreamTPI, TI))
323606c3fb27SDimitry Andric     return static_cast<LVType *>(Element);
323706c3fb27SDimitry Andric 
323806c3fb27SDimitry Andric   LVType *Pointee = createBaseType(TI, TypeName.drop_back(1));
323906c3fb27SDimitry Andric   if (createElement(TI, TypeLeafKind::LF_POINTER)) {
324006c3fb27SDimitry Andric     CurrentType->setIsFinalized();
324106c3fb27SDimitry Andric     CurrentType->setType(Pointee);
324206c3fb27SDimitry Andric     Reader->getCompileUnit()->addElement(CurrentType);
324306c3fb27SDimitry Andric   }
324406c3fb27SDimitry Andric   return CurrentType;
324506c3fb27SDimitry Andric }
324606c3fb27SDimitry Andric 
createParents(StringRef ScopedName,LVElement * Element)324706c3fb27SDimitry Andric void LVLogicalVisitor::createParents(StringRef ScopedName, LVElement *Element) {
324806c3fb27SDimitry Andric   // For the given test case:
324906c3fb27SDimitry Andric   //
325006c3fb27SDimitry Andric   // struct S { enum E { ... }; };
325106c3fb27SDimitry Andric   // S::E V;
325206c3fb27SDimitry Andric   //
325306c3fb27SDimitry Andric   //      0 | S_LOCAL `V`
325406c3fb27SDimitry Andric   //          type=0x1004 (S::E), flags = none
325506c3fb27SDimitry Andric   // 0x1004 | LF_ENUM  `S::E`
325606c3fb27SDimitry Andric   //          options: has unique name | is nested
325706c3fb27SDimitry Andric   // 0x1009 | LF_STRUCTURE `S`
325806c3fb27SDimitry Andric   //          options: contains nested class
325906c3fb27SDimitry Andric   //
326006c3fb27SDimitry Andric   // When the local 'V' is processed, its type 'E' is created. But There is
326106c3fb27SDimitry Andric   // no direct reference to its parent 'S'. We use the scoped name for 'E',
326206c3fb27SDimitry Andric   // to create its parents.
326306c3fb27SDimitry Andric 
326406c3fb27SDimitry Andric   // The input scoped name must have at least parent and nested names.
326506c3fb27SDimitry Andric   // Drop the last element name, as it corresponds to the nested type.
326606c3fb27SDimitry Andric   LVStringRefs Components = getAllLexicalComponents(ScopedName);
326706c3fb27SDimitry Andric   if (Components.size() < 2)
326806c3fb27SDimitry Andric     return;
326906c3fb27SDimitry Andric   Components.pop_back();
327006c3fb27SDimitry Andric 
327106c3fb27SDimitry Andric   LVStringRefs::size_type FirstNamespace;
327206c3fb27SDimitry Andric   LVStringRefs::size_type FirstAggregate;
327306c3fb27SDimitry Andric   std::tie(FirstNamespace, FirstAggregate) =
327406c3fb27SDimitry Andric       Shared->NamespaceDeduction.find(Components);
327506c3fb27SDimitry Andric 
327606c3fb27SDimitry Andric   LLVM_DEBUG({
327706c3fb27SDimitry Andric     W.printString("First Namespace", Components[FirstNamespace]);
327806c3fb27SDimitry Andric     W.printString("First NonNamespace", Components[FirstAggregate]);
327906c3fb27SDimitry Andric   });
328006c3fb27SDimitry Andric 
328106c3fb27SDimitry Andric   // Create any referenced namespaces.
328206c3fb27SDimitry Andric   if (FirstNamespace < FirstAggregate) {
328306c3fb27SDimitry Andric     Shared->NamespaceDeduction.get(
328406c3fb27SDimitry Andric         LVStringRefs(Components.begin() + FirstNamespace,
328506c3fb27SDimitry Andric                      Components.begin() + FirstAggregate));
328606c3fb27SDimitry Andric   }
328706c3fb27SDimitry Andric 
328806c3fb27SDimitry Andric   // Traverse the enclosing scopes (aggregates) and create them. In the
328906c3fb27SDimitry Andric   // case of nested empty aggregates, MSVC does not emit a full record
329006c3fb27SDimitry Andric   // description. It emits only the reference record.
329106c3fb27SDimitry Andric   LVScope *Aggregate = nullptr;
329206c3fb27SDimitry Andric   TypeIndex TIAggregate;
329306c3fb27SDimitry Andric   std::string AggregateName = getScopedName(
329406c3fb27SDimitry Andric       LVStringRefs(Components.begin(), Components.begin() + FirstAggregate));
329506c3fb27SDimitry Andric 
329606c3fb27SDimitry Andric   // This traversal is executed at least once.
329706c3fb27SDimitry Andric   for (LVStringRefs::size_type Index = FirstAggregate;
329806c3fb27SDimitry Andric        Index < Components.size(); ++Index) {
329906c3fb27SDimitry Andric     AggregateName = getScopedName(LVStringRefs(Components.begin() + Index,
330006c3fb27SDimitry Andric                                                Components.begin() + Index + 1),
330106c3fb27SDimitry Andric                                   AggregateName);
330206c3fb27SDimitry Andric     TIAggregate = Shared->ForwardReferences.remap(
330306c3fb27SDimitry Andric         Shared->TypeRecords.find(StreamTPI, AggregateName));
330406c3fb27SDimitry Andric     Aggregate =
330506c3fb27SDimitry Andric         TIAggregate.isNoneType()
330606c3fb27SDimitry Andric             ? nullptr
330706c3fb27SDimitry Andric             : static_cast<LVScope *>(getElement(StreamTPI, TIAggregate));
330806c3fb27SDimitry Andric   }
330906c3fb27SDimitry Andric 
331006c3fb27SDimitry Andric   // Workaround for cases where LF_NESTTYPE is missing for nested templates.
331106c3fb27SDimitry Andric   // If we manage to get parent information from the scoped name, we can add
331206c3fb27SDimitry Andric   // the nested type without relying on the LF_NESTTYPE.
331306c3fb27SDimitry Andric   if (Aggregate && !Element->getIsScopedAlready()) {
331406c3fb27SDimitry Andric     Aggregate->addElement(Element);
331506c3fb27SDimitry Andric     Element->setIsScopedAlready();
331606c3fb27SDimitry Andric   }
331706c3fb27SDimitry Andric }
331806c3fb27SDimitry Andric 
getElement(uint32_t StreamIdx,TypeIndex TI,LVScope * Parent)331906c3fb27SDimitry Andric LVElement *LVLogicalVisitor::getElement(uint32_t StreamIdx, TypeIndex TI,
332006c3fb27SDimitry Andric                                         LVScope *Parent) {
332106c3fb27SDimitry Andric   LLVM_DEBUG({ printTypeIndex("TypeIndex", TI, StreamTPI); });
332206c3fb27SDimitry Andric   TI = Shared->ForwardReferences.remap(TI);
332306c3fb27SDimitry Andric   LLVM_DEBUG({ printTypeIndex("TypeIndex Remap", TI, StreamTPI); });
332406c3fb27SDimitry Andric 
332506c3fb27SDimitry Andric   LVElement *Element = Shared->TypeRecords.find(StreamIdx, TI);
332606c3fb27SDimitry Andric   if (!Element) {
332706c3fb27SDimitry Andric     if (TI.isNoneType() || TI.isSimple()) {
332806c3fb27SDimitry Andric       StringRef TypeName = TypeIndex::simpleTypeName(TI);
332906c3fb27SDimitry Andric       // If the name ends with "*", create 2 logical types: a pointer and a
333006c3fb27SDimitry Andric       // pointee type. TypeIndex is composed of a SympleTypeMode byte followed
333106c3fb27SDimitry Andric       // by a SimpleTypeKind byte. The logical pointer will be identified by
333206c3fb27SDimitry Andric       // the full TypeIndex value and the pointee by the SimpleTypeKind.
333306c3fb27SDimitry Andric       return (TypeName.back() == '*') ? createPointerType(TI, TypeName)
333406c3fb27SDimitry Andric                                       : createBaseType(TI, TypeName);
333506c3fb27SDimitry Andric     }
333606c3fb27SDimitry Andric 
333706c3fb27SDimitry Andric     LLVM_DEBUG({ W.printHex("TypeIndex not implemented: ", TI.getIndex()); });
333806c3fb27SDimitry Andric     return nullptr;
333906c3fb27SDimitry Andric   }
334006c3fb27SDimitry Andric 
334106c3fb27SDimitry Andric   // The element has been finalized.
334206c3fb27SDimitry Andric   if (Element->getIsFinalized())
334306c3fb27SDimitry Andric     return Element;
334406c3fb27SDimitry Andric 
334506c3fb27SDimitry Andric   // Add the element in case of a given parent.
334606c3fb27SDimitry Andric   if (Parent)
334706c3fb27SDimitry Andric     Parent->addElement(Element);
334806c3fb27SDimitry Andric 
334906c3fb27SDimitry Andric   // Check for a composite type.
335006c3fb27SDimitry Andric   LazyRandomTypeCollection &Types = types();
335106c3fb27SDimitry Andric   CVType CVRecord = Types.getType(TI);
335206c3fb27SDimitry Andric   if (Error Err = finishVisitation(CVRecord, TI, Element)) {
335306c3fb27SDimitry Andric     consumeError(std::move(Err));
335406c3fb27SDimitry Andric     return nullptr;
335506c3fb27SDimitry Andric   }
335606c3fb27SDimitry Andric   Element->setIsFinalized();
335706c3fb27SDimitry Andric   return Element;
335806c3fb27SDimitry Andric }
335906c3fb27SDimitry Andric 
processLines()336006c3fb27SDimitry Andric void LVLogicalVisitor::processLines() {
336106c3fb27SDimitry Andric   // Traverse the collected LF_UDT_SRC_LINE records and add the source line
336206c3fb27SDimitry Andric   // information to the logical elements.
336306c3fb27SDimitry Andric   for (const TypeIndex &Entry : Shared->LineRecords) {
336406c3fb27SDimitry Andric     CVType CVRecord = ids().getType(Entry);
336506c3fb27SDimitry Andric     UdtSourceLineRecord Line;
336606c3fb27SDimitry Andric     if (Error Err = TypeDeserializer::deserializeAs(
336706c3fb27SDimitry Andric             const_cast<CVType &>(CVRecord), Line))
336806c3fb27SDimitry Andric       consumeError(std::move(Err));
336906c3fb27SDimitry Andric     else {
337006c3fb27SDimitry Andric       LLVM_DEBUG({
337106c3fb27SDimitry Andric         printTypeIndex("UDT", Line.getUDT(), StreamIPI);
337206c3fb27SDimitry Andric         printTypeIndex("SourceFile", Line.getSourceFile(), StreamIPI);
337306c3fb27SDimitry Andric         W.printNumber("LineNumber", Line.getLineNumber());
337406c3fb27SDimitry Andric       });
337506c3fb27SDimitry Andric 
337606c3fb27SDimitry Andric       // The TypeIndex returned by 'getUDT()' must point to an already
337706c3fb27SDimitry Andric       // created logical element. If no logical element is found, it means
337806c3fb27SDimitry Andric       // the LF_UDT_SRC_LINE is associated with a system TypeIndex.
337906c3fb27SDimitry Andric       if (LVElement *Element = Shared->TypeRecords.find(
338006c3fb27SDimitry Andric               StreamTPI, Line.getUDT(), /*Create=*/false)) {
338106c3fb27SDimitry Andric         Element->setLineNumber(Line.getLineNumber());
338206c3fb27SDimitry Andric         Element->setFilenameIndex(
338306c3fb27SDimitry Andric             Shared->StringRecords.findIndex(Line.getSourceFile()));
338406c3fb27SDimitry Andric       }
338506c3fb27SDimitry Andric     }
338606c3fb27SDimitry Andric   }
338706c3fb27SDimitry Andric }
338806c3fb27SDimitry Andric 
processNamespaces()338906c3fb27SDimitry Andric void LVLogicalVisitor::processNamespaces() {
339006c3fb27SDimitry Andric   // Create namespaces.
339106c3fb27SDimitry Andric   Shared->NamespaceDeduction.init();
339206c3fb27SDimitry Andric }
339306c3fb27SDimitry Andric 
processFiles()339406c3fb27SDimitry Andric void LVLogicalVisitor::processFiles() { Shared->StringRecords.addFilenames(); }
339506c3fb27SDimitry Andric 
printRecords(raw_ostream & OS) const339606c3fb27SDimitry Andric void LVLogicalVisitor::printRecords(raw_ostream &OS) const {
339706c3fb27SDimitry Andric   if (!options().getInternalTag())
339806c3fb27SDimitry Andric     return;
339906c3fb27SDimitry Andric 
340006c3fb27SDimitry Andric   unsigned Count = 0;
340106c3fb27SDimitry Andric   auto PrintItem = [&](StringRef Name) {
340206c3fb27SDimitry Andric     auto NewLine = [&]() {
340306c3fb27SDimitry Andric       if (++Count == 4) {
340406c3fb27SDimitry Andric         Count = 0;
340506c3fb27SDimitry Andric         OS << "\n";
340606c3fb27SDimitry Andric       }
340706c3fb27SDimitry Andric     };
340806c3fb27SDimitry Andric     OS << format("%20s", Name.str().c_str());
340906c3fb27SDimitry Andric     NewLine();
341006c3fb27SDimitry Andric   };
341106c3fb27SDimitry Andric 
341206c3fb27SDimitry Andric   OS << "\nTypes:\n";
341306c3fb27SDimitry Andric   for (const TypeLeafKind &Kind : Shared->TypeKinds)
341406c3fb27SDimitry Andric     PrintItem(formatTypeLeafKind(Kind));
341506c3fb27SDimitry Andric   Shared->TypeKinds.clear();
341606c3fb27SDimitry Andric 
341706c3fb27SDimitry Andric   Count = 0;
341806c3fb27SDimitry Andric   OS << "\nSymbols:\n";
341906c3fb27SDimitry Andric   for (const SymbolKind &Kind : Shared->SymbolKinds)
342006c3fb27SDimitry Andric     PrintItem(LVCodeViewReader::getSymbolKindName(Kind));
342106c3fb27SDimitry Andric   Shared->SymbolKinds.clear();
342206c3fb27SDimitry Andric 
342306c3fb27SDimitry Andric   OS << "\n";
342406c3fb27SDimitry Andric }
342506c3fb27SDimitry Andric 
inlineSiteAnnotation(LVScope * AbstractFunction,LVScope * InlinedFunction,InlineSiteSym & InlineSite)342606c3fb27SDimitry Andric Error LVLogicalVisitor::inlineSiteAnnotation(LVScope *AbstractFunction,
342706c3fb27SDimitry Andric                                              LVScope *InlinedFunction,
342806c3fb27SDimitry Andric                                              InlineSiteSym &InlineSite) {
342906c3fb27SDimitry Andric   // Get the parent scope to update the address ranges of the nested
343006c3fb27SDimitry Andric   // scope representing the inlined function.
343106c3fb27SDimitry Andric   LVAddress ParentLowPC = 0;
343206c3fb27SDimitry Andric   LVScope *Parent = InlinedFunction->getParentScope();
343306c3fb27SDimitry Andric   if (const LVLocations *Locations = Parent->getRanges()) {
343406c3fb27SDimitry Andric     if (!Locations->empty())
343506c3fb27SDimitry Andric       ParentLowPC = (*Locations->begin())->getLowerAddress();
343606c3fb27SDimitry Andric   }
343706c3fb27SDimitry Andric 
343806c3fb27SDimitry Andric   // For the given inlinesite, get the initial line number and its
343906c3fb27SDimitry Andric   // source filename. Update the logical scope representing it.
344006c3fb27SDimitry Andric   uint32_t LineNumber = 0;
344106c3fb27SDimitry Andric   StringRef Filename;
344206c3fb27SDimitry Andric   LVInlineeInfo::iterator Iter = InlineeInfo.find(InlineSite.Inlinee);
344306c3fb27SDimitry Andric   if (Iter != InlineeInfo.end()) {
344406c3fb27SDimitry Andric     LineNumber = Iter->second.first;
344506c3fb27SDimitry Andric     Filename = Iter->second.second;
344606c3fb27SDimitry Andric     AbstractFunction->setLineNumber(LineNumber);
344706c3fb27SDimitry Andric     // TODO: This part needs additional work in order to set properly the
344806c3fb27SDimitry Andric     // correct filename in order to detect changes between filenames.
344906c3fb27SDimitry Andric     // AbstractFunction->setFilename(Filename);
345006c3fb27SDimitry Andric   }
345106c3fb27SDimitry Andric 
345206c3fb27SDimitry Andric   LLVM_DEBUG({
345306c3fb27SDimitry Andric     dbgs() << "inlineSiteAnnotation\n"
345406c3fb27SDimitry Andric            << "Abstract: " << AbstractFunction->getName() << "\n"
345506c3fb27SDimitry Andric            << "Inlined: " << InlinedFunction->getName() << "\n"
345606c3fb27SDimitry Andric            << "Parent: " << Parent->getName() << "\n"
345706c3fb27SDimitry Andric            << "Low PC: " << hexValue(ParentLowPC) << "\n";
345806c3fb27SDimitry Andric   });
345906c3fb27SDimitry Andric 
346006c3fb27SDimitry Andric   // Get the source lines if requested by command line option.
346106c3fb27SDimitry Andric   if (!options().getPrintLines())
346206c3fb27SDimitry Andric     return Error::success();
346306c3fb27SDimitry Andric 
346406c3fb27SDimitry Andric   // Limitation: Currently we don't track changes in the FileOffset. The
346506c3fb27SDimitry Andric   // side effects are the caller that it is unable to differentiate the
346606c3fb27SDimitry Andric   // source filename for the inlined code.
346706c3fb27SDimitry Andric   uint64_t CodeOffset = ParentLowPC;
346806c3fb27SDimitry Andric   int32_t LineOffset = LineNumber;
346906c3fb27SDimitry Andric   uint32_t FileOffset = 0;
347006c3fb27SDimitry Andric 
347106c3fb27SDimitry Andric   auto UpdateClose = [&]() { LLVM_DEBUG({ dbgs() << ("\n"); }); };
347206c3fb27SDimitry Andric   auto UpdateCodeOffset = [&](uint32_t Delta) {
347306c3fb27SDimitry Andric     CodeOffset += Delta;
347406c3fb27SDimitry Andric     LLVM_DEBUG({
347506c3fb27SDimitry Andric       dbgs() << formatv(" code 0x{0} (+0x{1})", utohexstr(CodeOffset),
347606c3fb27SDimitry Andric                         utohexstr(Delta));
347706c3fb27SDimitry Andric     });
347806c3fb27SDimitry Andric   };
347906c3fb27SDimitry Andric   auto UpdateLineOffset = [&](int32_t Delta) {
348006c3fb27SDimitry Andric     LineOffset += Delta;
348106c3fb27SDimitry Andric     LLVM_DEBUG({
348206c3fb27SDimitry Andric       char Sign = Delta > 0 ? '+' : '-';
348306c3fb27SDimitry Andric       dbgs() << formatv(" line {0} ({1}{2})", LineOffset, Sign,
348406c3fb27SDimitry Andric                         std::abs(Delta));
348506c3fb27SDimitry Andric     });
348606c3fb27SDimitry Andric   };
348706c3fb27SDimitry Andric   auto UpdateFileOffset = [&](int32_t Offset) {
348806c3fb27SDimitry Andric     FileOffset = Offset;
348906c3fb27SDimitry Andric     LLVM_DEBUG({ dbgs() << formatv(" file {0}", FileOffset); });
349006c3fb27SDimitry Andric   };
349106c3fb27SDimitry Andric 
349206c3fb27SDimitry Andric   LVLines InlineeLines;
349306c3fb27SDimitry Andric   auto CreateLine = [&]() {
349406c3fb27SDimitry Andric     // Create the logical line record.
349506c3fb27SDimitry Andric     LVLineDebug *Line = Reader->createLineDebug();
349606c3fb27SDimitry Andric     Line->setAddress(CodeOffset);
349706c3fb27SDimitry Andric     Line->setLineNumber(LineOffset);
349806c3fb27SDimitry Andric     // TODO: This part needs additional work in order to set properly the
349906c3fb27SDimitry Andric     // correct filename in order to detect changes between filenames.
350006c3fb27SDimitry Andric     // Line->setFilename(Filename);
350106c3fb27SDimitry Andric     InlineeLines.push_back(Line);
350206c3fb27SDimitry Andric   };
350306c3fb27SDimitry Andric 
350406c3fb27SDimitry Andric   bool SeenLowAddress = false;
350506c3fb27SDimitry Andric   bool SeenHighAddress = false;
350606c3fb27SDimitry Andric   uint64_t LowPC = 0;
350706c3fb27SDimitry Andric   uint64_t HighPC = 0;
350806c3fb27SDimitry Andric 
350906c3fb27SDimitry Andric   for (auto &Annot : InlineSite.annotations()) {
351006c3fb27SDimitry Andric     LLVM_DEBUG({
351106c3fb27SDimitry Andric       dbgs() << formatv("  {0}",
351206c3fb27SDimitry Andric                         fmt_align(toHex(Annot.Bytes), AlignStyle::Left, 9));
351306c3fb27SDimitry Andric     });
351406c3fb27SDimitry Andric 
351506c3fb27SDimitry Andric     // Use the opcode to interpret the integer values.
351606c3fb27SDimitry Andric     switch (Annot.OpCode) {
351706c3fb27SDimitry Andric     case BinaryAnnotationsOpCode::ChangeCodeOffset:
351806c3fb27SDimitry Andric     case BinaryAnnotationsOpCode::CodeOffset:
351906c3fb27SDimitry Andric     case BinaryAnnotationsOpCode::ChangeCodeLength:
352006c3fb27SDimitry Andric       UpdateCodeOffset(Annot.U1);
352106c3fb27SDimitry Andric       UpdateClose();
352206c3fb27SDimitry Andric       if (Annot.OpCode == BinaryAnnotationsOpCode::ChangeCodeOffset) {
352306c3fb27SDimitry Andric         CreateLine();
352406c3fb27SDimitry Andric         LowPC = CodeOffset;
352506c3fb27SDimitry Andric         SeenLowAddress = true;
352606c3fb27SDimitry Andric         break;
352706c3fb27SDimitry Andric       }
352806c3fb27SDimitry Andric       if (Annot.OpCode == BinaryAnnotationsOpCode::ChangeCodeLength) {
352906c3fb27SDimitry Andric         HighPC = CodeOffset - 1;
353006c3fb27SDimitry Andric         SeenHighAddress = true;
353106c3fb27SDimitry Andric       }
353206c3fb27SDimitry Andric       break;
353306c3fb27SDimitry Andric     case BinaryAnnotationsOpCode::ChangeCodeLengthAndCodeOffset:
353406c3fb27SDimitry Andric       UpdateCodeOffset(Annot.U2);
353506c3fb27SDimitry Andric       UpdateClose();
353606c3fb27SDimitry Andric       break;
353706c3fb27SDimitry Andric     case BinaryAnnotationsOpCode::ChangeLineOffset:
353806c3fb27SDimitry Andric     case BinaryAnnotationsOpCode::ChangeCodeOffsetAndLineOffset:
353906c3fb27SDimitry Andric       UpdateCodeOffset(Annot.U1);
354006c3fb27SDimitry Andric       UpdateLineOffset(Annot.S1);
354106c3fb27SDimitry Andric       UpdateClose();
354206c3fb27SDimitry Andric       if (Annot.OpCode ==
354306c3fb27SDimitry Andric           BinaryAnnotationsOpCode::ChangeCodeOffsetAndLineOffset)
354406c3fb27SDimitry Andric         CreateLine();
354506c3fb27SDimitry Andric       break;
354606c3fb27SDimitry Andric     case BinaryAnnotationsOpCode::ChangeFile:
354706c3fb27SDimitry Andric       UpdateFileOffset(Annot.U1);
354806c3fb27SDimitry Andric       UpdateClose();
354906c3fb27SDimitry Andric       break;
355006c3fb27SDimitry Andric     default:
355106c3fb27SDimitry Andric       break;
355206c3fb27SDimitry Andric     }
355306c3fb27SDimitry Andric     if (SeenLowAddress && SeenHighAddress) {
355406c3fb27SDimitry Andric       SeenLowAddress = false;
355506c3fb27SDimitry Andric       SeenHighAddress = false;
355606c3fb27SDimitry Andric       InlinedFunction->addObject(LowPC, HighPC);
355706c3fb27SDimitry Andric     }
355806c3fb27SDimitry Andric   }
355906c3fb27SDimitry Andric 
356006c3fb27SDimitry Andric   Reader->addInlineeLines(InlinedFunction, InlineeLines);
356106c3fb27SDimitry Andric   UpdateClose();
356206c3fb27SDimitry Andric 
356306c3fb27SDimitry Andric   return Error::success();
356406c3fb27SDimitry Andric }
3565