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)
4685f757f3fSDimitry Andric llvm::erase_if(Components, [&](StringRef Component) {
4695f757f3fSDimitry Andric LookupSet::iterator Iter = IdentifiedNamespaces.find(Component);
47006c3fb27SDimitry Andric return Iter == IdentifiedNamespaces.end();
4715f757f3fSDimitry 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
837*0fca6ea1SDimitry Andric if (Local.Name == "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.
888*0fca6ea1SDimitry Andric if (Local.Name == "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) ||
1432*0fca6ea1SDimitry Andric Local.Name == "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);
1672*0fca6ea1SDimitry Andric if (UDT.Name == 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
16885f757f3fSDimitry Andric // S_ARMSWITCHTABLE
visitKnownRecord(CVSymbol & CVR,JumpTableSym & JumpTable)16895f757f3fSDimitry Andric Error LVSymbolVisitor::visitKnownRecord(CVSymbol &CVR,
16905f757f3fSDimitry Andric JumpTableSym &JumpTable) {
16915f757f3fSDimitry Andric LLVM_DEBUG({
16925f757f3fSDimitry Andric W.printHex("BaseOffset", JumpTable.BaseOffset);
16935f757f3fSDimitry Andric W.printNumber("BaseSegment", JumpTable.BaseSegment);
16945f757f3fSDimitry Andric W.printFlags("SwitchType", static_cast<uint16_t>(JumpTable.SwitchType),
16955f757f3fSDimitry Andric getJumpTableEntrySizeNames());
16965f757f3fSDimitry Andric W.printHex("BranchOffset", JumpTable.BranchOffset);
16975f757f3fSDimitry Andric W.printHex("TableOffset", JumpTable.TableOffset);
16985f757f3fSDimitry Andric W.printNumber("BranchSegment", JumpTable.BranchSegment);
16995f757f3fSDimitry Andric W.printNumber("TableSegment", JumpTable.TableSegment);
17005f757f3fSDimitry Andric W.printNumber("EntriesCount", JumpTable.EntriesCount);
17015f757f3fSDimitry Andric });
17025f757f3fSDimitry Andric return Error::success();
17035f757f3fSDimitry Andric }
17045f757f3fSDimitry Andric
17055f757f3fSDimitry Andric // S_CALLERS, S_CALLEES, S_INLINEES
visitKnownRecord(CVSymbol & Record,CallerSym & Caller)17065f757f3fSDimitry Andric Error LVSymbolVisitor::visitKnownRecord(CVSymbol &Record, CallerSym &Caller) {
17075f757f3fSDimitry Andric LLVM_DEBUG({
17085f757f3fSDimitry Andric llvm::StringRef FieldName;
17095f757f3fSDimitry Andric switch (Caller.getKind()) {
17105f757f3fSDimitry Andric case SymbolRecordKind::CallerSym:
17115f757f3fSDimitry Andric FieldName = "Callee";
17125f757f3fSDimitry Andric break;
17135f757f3fSDimitry Andric case SymbolRecordKind::CalleeSym:
17145f757f3fSDimitry Andric FieldName = "Caller";
17155f757f3fSDimitry Andric break;
17165f757f3fSDimitry Andric case SymbolRecordKind::InlineesSym:
17175f757f3fSDimitry Andric FieldName = "Inlinee";
17185f757f3fSDimitry Andric break;
17195f757f3fSDimitry Andric default:
17205f757f3fSDimitry Andric return llvm::make_error<CodeViewError>(
17215f757f3fSDimitry Andric "Unknown CV Record type for a CallerSym object!");
17225f757f3fSDimitry Andric }
17235f757f3fSDimitry Andric for (auto FuncID : Caller.Indices) {
17245f757f3fSDimitry Andric printTypeIndex(FieldName, FuncID);
17255f757f3fSDimitry Andric }
17265f757f3fSDimitry Andric });
17275f757f3fSDimitry Andric return Error::success();
17285f757f3fSDimitry Andric }
17295f757f3fSDimitry 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.
2743*0fca6ea1SDimitry Andric if (OuterComponent.size() && OuterComponent == 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) {
29395f757f3fSDimitry 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