Path: blob/main/contrib/llvm-project/llvm/lib/DebugInfo/LogicalView/Readers/LVCodeViewVisitor.cpp
35295 views
//===-- LVCodeViewVisitor.cpp ---------------------------------------------===//1//2// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.3// See https://llvm.org/LICENSE.txt for license information.4// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception5//6//===----------------------------------------------------------------------===//7//8// This implements the LVCodeViewVisitor class.9//10//===----------------------------------------------------------------------===//1112#include "llvm/DebugInfo/LogicalView/Readers/LVCodeViewVisitor.h"13#include "llvm/BinaryFormat/Magic.h"14#include "llvm/DebugInfo/CodeView/EnumTables.h"15#include "llvm/DebugInfo/CodeView/LazyRandomTypeCollection.h"16#include "llvm/DebugInfo/CodeView/SymbolRecordHelpers.h"17#include "llvm/DebugInfo/CodeView/TypeRecordHelpers.h"18#include "llvm/DebugInfo/CodeView/TypeVisitorCallbackPipeline.h"19#include "llvm/DebugInfo/LogicalView/Core/LVScope.h"20#include "llvm/DebugInfo/LogicalView/Core/LVSymbol.h"21#include "llvm/DebugInfo/LogicalView/Core/LVType.h"22#include "llvm/DebugInfo/LogicalView/Readers/LVCodeViewReader.h"23#include "llvm/DebugInfo/PDB/Native/DbiStream.h"24#include "llvm/DebugInfo/PDB/Native/InputFile.h"25#include "llvm/DebugInfo/PDB/Native/NativeSession.h"26#include "llvm/DebugInfo/PDB/Native/PDBFile.h"27#include "llvm/DebugInfo/PDB/Native/PDBStringTable.h"28#include "llvm/DebugInfo/PDB/Native/RawError.h"29#include "llvm/DebugInfo/PDB/Native/TpiStream.h"30#include "llvm/DebugInfo/PDB/PDB.h"31#include "llvm/Demangle/Demangle.h"32#include "llvm/Object/COFF.h"33#include "llvm/Support/Error.h"34#include "llvm/Support/FileSystem.h"35#include "llvm/Support/FormatAdapters.h"36#include "llvm/Support/FormatVariadic.h"3738using namespace llvm;39using namespace llvm::codeview;40using namespace llvm::object;41using namespace llvm::pdb;42using namespace llvm::logicalview;4344#define DEBUG_TYPE "CodeViewUtilities"4546namespace llvm {47namespace logicalview {4849static TypeIndex getTrueType(TypeIndex &TI) {50// Dealing with a MSVC generated PDB, we encountered a type index with the51// value of: 0x0280xxxx where xxxx=0000.52//53// There is some documentation about type indices:54// https://llvm.org/docs/PDB/TpiStream.html55//56// A type index is a 32-bit integer that uniquely identifies a type inside57// of an object file’s .debug$T section or a PDB file’s TPI or IPI stream.58// The value of the type index for the first type record from the TPI stream59// is given by the TypeIndexBegin member of the TPI Stream Header although60// in practice this value is always equal to 0x1000 (4096).61//62// Any type index with a high bit set is considered to come from the IPI63// stream, although this appears to be more of a hack, and LLVM does not64// generate type indices of this nature. They can, however, be observed in65// Microsoft PDBs occasionally, so one should be prepared to handle them.66// Note that having the high bit set is not a necessary condition to67// determine whether a type index comes from the IPI stream, it is only68// sufficient.69LLVM_DEBUG(70{ dbgs() << "Index before: " << HexNumber(TI.getIndex()) << "\n"; });71TI.setIndex(TI.getIndex() & 0x0000ffff);72LLVM_DEBUG(73{ dbgs() << "Index after: " << HexNumber(TI.getIndex()) << "\n"; });74return TI;75}7677static const EnumEntry<TypeLeafKind> LeafTypeNames[] = {78#define CV_TYPE(enum, val) {#enum, enum},79#include "llvm/DebugInfo/CodeView/CodeViewTypes.def"80};8182// Return the type name pointed by the type index. It uses the kind to query83// the associated name for the record type.84static StringRef getRecordName(LazyRandomTypeCollection &Types, TypeIndex TI) {85if (TI.isSimple())86return {};8788StringRef RecordName;89CVType CVReference = Types.getType(TI);90auto GetName = [&](auto Record) {91if (Error Err = TypeDeserializer::deserializeAs(92const_cast<CVType &>(CVReference), Record))93consumeError(std::move(Err));94else95RecordName = Record.getName();96};9798TypeRecordKind RK = static_cast<TypeRecordKind>(CVReference.kind());99if (RK == TypeRecordKind::Class || RK == TypeRecordKind::Struct)100GetName(ClassRecord(RK));101else if (RK == TypeRecordKind::Union)102GetName(UnionRecord(RK));103else if (RK == TypeRecordKind::Enum)104GetName(EnumRecord(RK));105106return RecordName;107}108109} // namespace logicalview110} // namespace llvm111112#undef DEBUG_TYPE113#define DEBUG_TYPE "CodeViewDataVisitor"114115namespace llvm {116namespace logicalview {117118// Keeps the type indexes with line information.119using LVLineRecords = std::vector<TypeIndex>;120121namespace {122123class LVTypeRecords {124LVShared *Shared = nullptr;125126// Logical elements associated to their CodeView Type Index.127using RecordEntry = std::pair<TypeLeafKind, LVElement *>;128using RecordTable = std::map<TypeIndex, RecordEntry>;129RecordTable RecordFromTypes;130RecordTable RecordFromIds;131132using NameTable = std::map<StringRef, TypeIndex>;133NameTable NameFromTypes;134NameTable NameFromIds;135136public:137LVTypeRecords(LVShared *Shared) : Shared(Shared) {}138139void add(uint32_t StreamIdx, TypeIndex TI, TypeLeafKind Kind,140LVElement *Element = nullptr);141void add(uint32_t StreamIdx, TypeIndex TI, StringRef Name);142LVElement *find(uint32_t StreamIdx, TypeIndex TI, bool Create = true);143TypeIndex find(uint32_t StreamIdx, StringRef Name);144};145146class LVForwardReferences {147// Forward reference and its definitions (Name as key).148using ForwardEntry = std::pair<TypeIndex, TypeIndex>;149using ForwardTypeNames = std::map<StringRef, ForwardEntry>;150ForwardTypeNames ForwardTypesNames;151152// Forward reference and its definition (TypeIndex as key).153using ForwardType = std::map<TypeIndex, TypeIndex>;154ForwardType ForwardTypes;155156// Forward types and its references.157void add(TypeIndex TIForward, TypeIndex TIReference) {158ForwardTypes.emplace(TIForward, TIReference);159}160161void add(StringRef Name, TypeIndex TIForward) {162if (ForwardTypesNames.find(Name) == ForwardTypesNames.end()) {163ForwardTypesNames.emplace(164std::piecewise_construct, std::forward_as_tuple(Name),165std::forward_as_tuple(TIForward, TypeIndex::None()));166} else {167// Update a recorded definition with its reference.168ForwardTypesNames[Name].first = TIForward;169add(TIForward, ForwardTypesNames[Name].second);170}171}172173// Update a previously recorded forward reference with its definition.174void update(StringRef Name, TypeIndex TIReference) {175if (ForwardTypesNames.find(Name) != ForwardTypesNames.end()) {176// Update the recorded forward reference with its definition.177ForwardTypesNames[Name].second = TIReference;178add(ForwardTypesNames[Name].first, TIReference);179} else {180// We have not seen the forward reference. Insert the definition.181ForwardTypesNames.emplace(182std::piecewise_construct, std::forward_as_tuple(Name),183std::forward_as_tuple(TypeIndex::None(), TIReference));184}185}186187public:188LVForwardReferences() = default;189190void record(bool IsForwardRef, StringRef Name, TypeIndex TI) {191// We are expecting for the forward references to be first. But that192// is not always the case. A name must be recorded regardless of the193// order in which the forward reference appears.194(IsForwardRef) ? add(Name, TI) : update(Name, TI);195}196197TypeIndex find(TypeIndex TIForward) {198return (ForwardTypes.find(TIForward) != ForwardTypes.end())199? ForwardTypes[TIForward]200: TypeIndex::None();201}202203TypeIndex find(StringRef Name) {204return (ForwardTypesNames.find(Name) != ForwardTypesNames.end())205? ForwardTypesNames[Name].second206: TypeIndex::None();207}208209// If the given TI corresponds to a reference, return the reference.210// Otherwise return the given TI.211TypeIndex remap(TypeIndex TI) {212TypeIndex Forward = find(TI);213return Forward.isNoneType() ? TI : Forward;214}215};216217// Namespace deduction.218class LVNamespaceDeduction {219LVShared *Shared = nullptr;220221using Names = std::map<StringRef, LVScope *>;222Names NamespaceNames;223224using LookupSet = std::set<StringRef>;225LookupSet DeducedScopes;226LookupSet UnresolvedScopes;227LookupSet IdentifiedNamespaces;228229void add(StringRef Name, LVScope *Namespace) {230if (NamespaceNames.find(Name) == NamespaceNames.end())231NamespaceNames.emplace(Name, Namespace);232}233234public:235LVNamespaceDeduction(LVShared *Shared) : Shared(Shared) {}236237void init();238void add(StringRef String);239LVScope *get(LVStringRefs Components);240LVScope *get(StringRef Name, bool CheckScope = true);241242// Find the logical namespace for the 'Name' component.243LVScope *find(StringRef Name) {244LVScope *Namespace = (NamespaceNames.find(Name) != NamespaceNames.end())245? NamespaceNames[Name]246: nullptr;247return Namespace;248}249250// For the given lexical components, return a tuple with the first entry251// being the outermost namespace and the second entry being the first252// non-namespace.253LVLexicalIndex find(LVStringRefs Components) {254if (Components.empty())255return {};256257LVStringRefs::size_type FirstNamespace = 0;258LVStringRefs::size_type FirstNonNamespace;259for (LVStringRefs::size_type Index = 0; Index < Components.size();260++Index) {261FirstNonNamespace = Index;262LookupSet::iterator Iter = IdentifiedNamespaces.find(Components[Index]);263if (Iter == IdentifiedNamespaces.end())264// The component is not a namespace name.265break;266}267return std::make_tuple(FirstNamespace, FirstNonNamespace);268}269};270271// Strings.272class LVStringRecords {273using StringEntry = std::tuple<uint32_t, std::string, LVScopeCompileUnit *>;274using StringIds = std::map<TypeIndex, StringEntry>;275StringIds Strings;276277public:278LVStringRecords() = default;279280void add(TypeIndex TI, StringRef String) {281static uint32_t Index = 0;282if (Strings.find(TI) == Strings.end())283Strings.emplace(284std::piecewise_construct, std::forward_as_tuple(TI),285std::forward_as_tuple(++Index, std::string(String), nullptr));286}287288StringRef find(TypeIndex TI) {289StringIds::iterator Iter = Strings.find(TI);290return Iter != Strings.end() ? std::get<1>(Iter->second) : StringRef{};291}292293uint32_t findIndex(TypeIndex TI) {294StringIds::iterator Iter = Strings.find(TI);295return Iter != Strings.end() ? std::get<0>(Iter->second) : 0;296}297298// Move strings representing the filenames to the compile unit.299void addFilenames();300void addFilenames(LVScopeCompileUnit *Scope);301};302} // namespace303304using LVTypeKinds = std::set<TypeLeafKind>;305using LVSymbolKinds = std::set<SymbolKind>;306307// The following data keeps forward information, type records, names for308// namespace deduction, strings records, line records.309// It is shared by the type visitor, symbol visitor and logical visitor and310// it is independent from the CodeViewReader.311struct LVShared {312LVCodeViewReader *Reader;313LVLogicalVisitor *Visitor;314LVForwardReferences ForwardReferences;315LVLineRecords LineRecords;316LVNamespaceDeduction NamespaceDeduction;317LVStringRecords StringRecords;318LVTypeRecords TypeRecords;319320// In order to determine which types and/or symbols records should be handled321// by the reader, we record record kinds seen by the type and symbol visitors.322// At the end of the scopes creation, the '--internal=tag' option will allow323// to print the unique record ids collected.324LVTypeKinds TypeKinds;325LVSymbolKinds SymbolKinds;326327LVShared(LVCodeViewReader *Reader, LVLogicalVisitor *Visitor)328: Reader(Reader), Visitor(Visitor), NamespaceDeduction(this),329TypeRecords(this) {}330~LVShared() = default;331};332} // namespace logicalview333} // namespace llvm334335void LVTypeRecords::add(uint32_t StreamIdx, TypeIndex TI, TypeLeafKind Kind,336LVElement *Element) {337RecordTable &Target =338(StreamIdx == StreamTPI) ? RecordFromTypes : RecordFromIds;339Target.emplace(std::piecewise_construct, std::forward_as_tuple(TI),340std::forward_as_tuple(Kind, Element));341}342343void LVTypeRecords::add(uint32_t StreamIdx, TypeIndex TI, StringRef Name) {344NameTable &Target = (StreamIdx == StreamTPI) ? NameFromTypes : NameFromIds;345Target.emplace(Name, TI);346}347348LVElement *LVTypeRecords::find(uint32_t StreamIdx, TypeIndex TI, bool Create) {349RecordTable &Target =350(StreamIdx == StreamTPI) ? RecordFromTypes : RecordFromIds;351352LVElement *Element = nullptr;353RecordTable::iterator Iter = Target.find(TI);354if (Iter != Target.end()) {355Element = Iter->second.second;356if (Element || !Create)357return Element;358359// Create the logical element if not found.360Element = Shared->Visitor->createElement(Iter->second.first);361if (Element) {362Element->setOffset(TI.getIndex());363Element->setOffsetFromTypeIndex();364Target[TI].second = Element;365}366}367return Element;368}369370TypeIndex LVTypeRecords::find(uint32_t StreamIdx, StringRef Name) {371NameTable &Target = (StreamIdx == StreamTPI) ? NameFromTypes : NameFromIds;372NameTable::iterator Iter = Target.find(Name);373return Iter != Target.end() ? Iter->second : TypeIndex::None();374}375376void LVStringRecords::addFilenames() {377for (StringIds::const_reference Entry : Strings) {378StringRef Name = std::get<1>(Entry.second);379LVScopeCompileUnit *Scope = std::get<2>(Entry.second);380Scope->addFilename(transformPath(Name));381}382Strings.clear();383}384385void LVStringRecords::addFilenames(LVScopeCompileUnit *Scope) {386for (StringIds::reference Entry : Strings)387if (!std::get<2>(Entry.second))388std::get<2>(Entry.second) = Scope;389}390391void LVNamespaceDeduction::add(StringRef String) {392StringRef InnerComponent;393StringRef OuterComponent;394std::tie(OuterComponent, InnerComponent) = getInnerComponent(String);395DeducedScopes.insert(InnerComponent);396if (OuterComponent.size())397UnresolvedScopes.insert(OuterComponent);398}399400void LVNamespaceDeduction::init() {401// We have 2 sets of names:402// - deduced scopes (class, structure, union and enum) and403// - unresolved scopes, that can represent namespaces or any deduced.404// Before creating the namespaces, we have to traverse the unresolved405// and remove any references to already deduced scopes.406LVStringRefs Components;407for (const StringRef &Unresolved : UnresolvedScopes) {408Components = getAllLexicalComponents(Unresolved);409for (const StringRef &Component : Components) {410LookupSet::iterator Iter = DeducedScopes.find(Component);411if (Iter == DeducedScopes.end())412IdentifiedNamespaces.insert(Component);413}414}415416LLVM_DEBUG({417auto Print = [&](LookupSet &Container, const char *Title) {418auto Header = [&]() {419dbgs() << formatv("\n{0}\n", fmt_repeat('=', 72));420dbgs() << formatv("{0}\n", Title);421dbgs() << formatv("{0}\n", fmt_repeat('=', 72));422};423Header();424for (const StringRef &Item : Container)425dbgs() << formatv("'{0}'\n", Item.str().c_str());426};427428Print(DeducedScopes, "Deducted Scopes");429Print(UnresolvedScopes, "Unresolved Scopes");430Print(IdentifiedNamespaces, "Namespaces");431});432}433434LVScope *LVNamespaceDeduction::get(LVStringRefs Components) {435LLVM_DEBUG({436for (const StringRef &Component : Components)437dbgs() << formatv("'{0}'\n", Component.str().c_str());438});439440if (Components.empty())441return nullptr;442443// Update the namespaces relationship.444LVScope *Namespace = nullptr;445LVScope *Parent = Shared->Reader->getCompileUnit();446for (const StringRef &Component : Components) {447// Check if we have seen the namespace.448Namespace = find(Component);449if (!Namespace) {450// We have identified namespaces that are generated by MSVC. Mark them451// as 'system' so they will be excluded from the logical view.452Namespace = Shared->Reader->createScopeNamespace();453Namespace->setTag(dwarf::DW_TAG_namespace);454Namespace->setName(Component);455Parent->addElement(Namespace);456getReader().isSystemEntry(Namespace);457add(Component, Namespace);458}459Parent = Namespace;460}461return Parent;462}463464LVScope *LVNamespaceDeduction::get(StringRef ScopedName, bool CheckScope) {465LVStringRefs Components = getAllLexicalComponents(ScopedName);466if (CheckScope)467llvm::erase_if(Components, [&](StringRef Component) {468LookupSet::iterator Iter = IdentifiedNamespaces.find(Component);469return Iter == IdentifiedNamespaces.end();470});471472LLVM_DEBUG(473{ dbgs() << formatv("ScopedName: '{0}'\n", ScopedName.str().c_str()); });474475return get(Components);476}477478#undef DEBUG_TYPE479#define DEBUG_TYPE "CodeViewTypeVisitor"480481//===----------------------------------------------------------------------===//482// TypeRecord traversal.483//===----------------------------------------------------------------------===//484void LVTypeVisitor::printTypeIndex(StringRef FieldName, TypeIndex TI,485uint32_t StreamIdx) const {486codeview::printTypeIndex(W, FieldName, TI,487StreamIdx == StreamTPI ? Types : Ids);488}489490Error LVTypeVisitor::visitTypeBegin(CVType &Record) {491return visitTypeBegin(Record, TypeIndex::fromArrayIndex(Types.size()));492}493494Error LVTypeVisitor::visitTypeBegin(CVType &Record, TypeIndex TI) {495LLVM_DEBUG({496W.getOStream() << formatTypeLeafKind(Record.kind());497W.getOStream() << " (" << HexNumber(TI.getIndex()) << ")\n";498});499500if (options().getInternalTag())501Shared->TypeKinds.insert(Record.kind());502503// The collected type records, will be use to create the logical elements504// during the symbols traversal when a type is referenced.505CurrentTypeIndex = TI;506Shared->TypeRecords.add(StreamIdx, TI, Record.kind());507return Error::success();508}509510Error LVTypeVisitor::visitUnknownType(CVType &Record) {511LLVM_DEBUG({ W.printNumber("Length", uint32_t(Record.content().size())); });512return Error::success();513}514515Error LVTypeVisitor::visitMemberBegin(CVMemberRecord &Record) {516LLVM_DEBUG({517W.startLine() << formatTypeLeafKind(Record.Kind);518W.getOStream() << " {\n";519W.indent();520});521return Error::success();522}523524Error LVTypeVisitor::visitMemberEnd(CVMemberRecord &Record) {525LLVM_DEBUG({526W.unindent();527W.startLine() << "}\n";528});529return Error::success();530}531532Error LVTypeVisitor::visitUnknownMember(CVMemberRecord &Record) {533LLVM_DEBUG({ W.printHex("UnknownMember", unsigned(Record.Kind)); });534return Error::success();535}536537// LF_BUILDINFO (TPI)/(IPI)538Error LVTypeVisitor::visitKnownRecord(CVType &Record, BuildInfoRecord &Args) {539// All the args are references into the TPI/IPI stream.540LLVM_DEBUG({541W.printNumber("NumArgs", static_cast<uint32_t>(Args.getArgs().size()));542ListScope Arguments(W, "Arguments");543for (TypeIndex Arg : Args.getArgs())544printTypeIndex("ArgType", Arg, StreamIPI);545});546547// Only add the strings that hold information about filenames. They will be548// used to complete the line/file information for the logical elements.549// There are other strings holding information about namespaces.550TypeIndex TI;551StringRef String;552553// Absolute CWD path554TI = Args.getArgs()[BuildInfoRecord::BuildInfoArg::CurrentDirectory];555String = Ids.getTypeName(TI);556if (!String.empty())557Shared->StringRecords.add(TI, String);558559// Get the compile unit name.560TI = Args.getArgs()[BuildInfoRecord::BuildInfoArg::SourceFile];561String = Ids.getTypeName(TI);562if (!String.empty())563Shared->StringRecords.add(TI, String);564LogicalVisitor->setCompileUnitName(std::string(String));565566return Error::success();567}568569// LF_CLASS, LF_STRUCTURE, LF_INTERFACE (TPI)570Error LVTypeVisitor::visitKnownRecord(CVType &Record, ClassRecord &Class) {571LLVM_DEBUG({572printTypeIndex("TypeIndex", CurrentTypeIndex, StreamTPI);573printTypeIndex("FieldListType", Class.getFieldList(), StreamTPI);574W.printString("Name", Class.getName());575});576577// Collect class name for scope deduction.578Shared->NamespaceDeduction.add(Class.getName());579Shared->ForwardReferences.record(Class.isForwardRef(), Class.getName(),580CurrentTypeIndex);581582// Collect class name for contained scopes deduction.583Shared->TypeRecords.add(StreamIdx, CurrentTypeIndex, Class.getName());584return Error::success();585}586587// LF_ENUM (TPI)588Error LVTypeVisitor::visitKnownRecord(CVType &Record, EnumRecord &Enum) {589LLVM_DEBUG({590printTypeIndex("TypeIndex", CurrentTypeIndex, StreamTPI);591printTypeIndex("FieldListType", Enum.getFieldList(), StreamTPI);592W.printString("Name", Enum.getName());593});594595// Collect enum name for scope deduction.596Shared->NamespaceDeduction.add(Enum.getName());597return Error::success();598}599600// LF_FUNC_ID (TPI)/(IPI)601Error LVTypeVisitor::visitKnownRecord(CVType &Record, FuncIdRecord &Func) {602LLVM_DEBUG({603printTypeIndex("TypeIndex", CurrentTypeIndex, StreamTPI);604printTypeIndex("Type", Func.getFunctionType(), StreamTPI);605printTypeIndex("Parent", Func.getParentScope(), StreamTPI);606W.printString("Name", Func.getName());607});608609// Collect function name for scope deduction.610Shared->NamespaceDeduction.add(Func.getName());611return Error::success();612}613614// LF_PROCEDURE (TPI)615Error LVTypeVisitor::visitKnownRecord(CVType &Record, ProcedureRecord &Proc) {616LLVM_DEBUG({617printTypeIndex("TypeIndex", CurrentTypeIndex, StreamTPI);618printTypeIndex("ReturnType", Proc.getReturnType(), StreamTPI);619W.printNumber("NumParameters", Proc.getParameterCount());620printTypeIndex("ArgListType", Proc.getArgumentList(), StreamTPI);621});622623// Collect procedure information as they can be referenced by typedefs.624Shared->TypeRecords.add(StreamTPI, CurrentTypeIndex, {});625return Error::success();626}627628// LF_STRING_ID (TPI)/(IPI)629Error LVTypeVisitor::visitKnownRecord(CVType &Record, StringIdRecord &String) {630// No additional references are needed.631LLVM_DEBUG({632printTypeIndex("Id", String.getId(), StreamIPI);633W.printString("StringData", String.getString());634});635return Error::success();636}637638// LF_UDT_SRC_LINE (TPI)/(IPI)639Error LVTypeVisitor::visitKnownRecord(CVType &Record,640UdtSourceLineRecord &Line) {641// UDT and SourceFile are references into the TPI/IPI stream.642LLVM_DEBUG({643printTypeIndex("UDT", Line.getUDT(), StreamIPI);644printTypeIndex("SourceFile", Line.getSourceFile(), StreamIPI);645W.printNumber("LineNumber", Line.getLineNumber());646});647648Shared->LineRecords.push_back(CurrentTypeIndex);649return Error::success();650}651652// LF_UNION (TPI)653Error LVTypeVisitor::visitKnownRecord(CVType &Record, UnionRecord &Union) {654LLVM_DEBUG({655W.printNumber("MemberCount", Union.getMemberCount());656printTypeIndex("FieldList", Union.getFieldList(), StreamTPI);657W.printNumber("SizeOf", Union.getSize());658W.printString("Name", Union.getName());659if (Union.hasUniqueName())660W.printString("UniqueName", Union.getUniqueName());661});662663// Collect union name for scope deduction.664Shared->NamespaceDeduction.add(Union.getName());665Shared->ForwardReferences.record(Union.isForwardRef(), Union.getName(),666CurrentTypeIndex);667668// Collect class name for contained scopes deduction.669Shared->TypeRecords.add(StreamIdx, CurrentTypeIndex, Union.getName());670return Error::success();671}672673#undef DEBUG_TYPE674#define DEBUG_TYPE "CodeViewSymbolVisitor"675676//===----------------------------------------------------------------------===//677// SymbolRecord traversal.678//===----------------------------------------------------------------------===//679void LVSymbolVisitorDelegate::printRelocatedField(StringRef Label,680uint32_t RelocOffset,681uint32_t Offset,682StringRef *RelocSym) {683Reader->printRelocatedField(Label, CoffSection, RelocOffset, Offset,684RelocSym);685}686687void LVSymbolVisitorDelegate::getLinkageName(uint32_t RelocOffset,688uint32_t Offset,689StringRef *RelocSym) {690Reader->getLinkageName(CoffSection, RelocOffset, Offset, RelocSym);691}692693StringRef694LVSymbolVisitorDelegate::getFileNameForFileOffset(uint32_t FileOffset) {695Expected<StringRef> Name = Reader->getFileNameForFileOffset(FileOffset);696if (!Name) {697consumeError(Name.takeError());698return {};699}700return *Name;701}702703DebugStringTableSubsectionRef LVSymbolVisitorDelegate::getStringTable() {704return Reader->CVStringTable;705}706707void LVSymbolVisitor::printLocalVariableAddrRange(708const LocalVariableAddrRange &Range, uint32_t RelocationOffset) {709DictScope S(W, "LocalVariableAddrRange");710if (ObjDelegate)711ObjDelegate->printRelocatedField("OffsetStart", RelocationOffset,712Range.OffsetStart);713W.printHex("ISectStart", Range.ISectStart);714W.printHex("Range", Range.Range);715}716717void LVSymbolVisitor::printLocalVariableAddrGap(718ArrayRef<LocalVariableAddrGap> Gaps) {719for (const LocalVariableAddrGap &Gap : Gaps) {720ListScope S(W, "LocalVariableAddrGap");721W.printHex("GapStartOffset", Gap.GapStartOffset);722W.printHex("Range", Gap.Range);723}724}725726void LVSymbolVisitor::printTypeIndex(StringRef FieldName, TypeIndex TI) const {727codeview::printTypeIndex(W, FieldName, TI, Types);728}729730Error LVSymbolVisitor::visitSymbolBegin(CVSymbol &Record) {731return visitSymbolBegin(Record, 0);732}733734Error LVSymbolVisitor::visitSymbolBegin(CVSymbol &Record, uint32_t Offset) {735SymbolKind Kind = Record.kind();736LLVM_DEBUG({737W.printNumber("Offset", Offset);738W.printEnum("Begin Kind", unsigned(Kind), getSymbolTypeNames());739});740741if (options().getInternalTag())742Shared->SymbolKinds.insert(Kind);743744LogicalVisitor->CurrentElement = LogicalVisitor->createElement(Kind);745if (!LogicalVisitor->CurrentElement) {746LLVM_DEBUG({747// We have an unsupported Symbol or Type Record.748// W.printEnum("Kind ignored", unsigned(Kind), getSymbolTypeNames());749});750return Error::success();751}752753// Offset carried by the traversal routines when dealing with streams.754CurrentOffset = Offset;755IsCompileUnit = false;756if (!LogicalVisitor->CurrentElement->getOffsetFromTypeIndex())757LogicalVisitor->CurrentElement->setOffset(Offset);758if (symbolOpensScope(Kind) || (IsCompileUnit = symbolIsCompileUnit(Kind))) {759assert(LogicalVisitor->CurrentScope && "Invalid scope!");760LogicalVisitor->addElement(LogicalVisitor->CurrentScope, IsCompileUnit);761} else {762if (LogicalVisitor->CurrentSymbol)763LogicalVisitor->addElement(LogicalVisitor->CurrentSymbol);764if (LogicalVisitor->CurrentType)765LogicalVisitor->addElement(LogicalVisitor->CurrentType);766}767768return Error::success();769}770771Error LVSymbolVisitor::visitSymbolEnd(CVSymbol &Record) {772SymbolKind Kind = Record.kind();773LLVM_DEBUG(774{ W.printEnum("End Kind", unsigned(Kind), getSymbolTypeNames()); });775776if (symbolEndsScope(Kind)) {777LogicalVisitor->popScope();778}779780return Error::success();781}782783Error LVSymbolVisitor::visitUnknownSymbol(CVSymbol &Record) {784LLVM_DEBUG({ W.printNumber("Length", Record.length()); });785return Error::success();786}787788// S_BLOCK32789Error LVSymbolVisitor::visitKnownRecord(CVSymbol &Record, BlockSym &Block) {790LLVM_DEBUG({791W.printHex("CodeSize", Block.CodeSize);792W.printHex("Segment", Block.Segment);793W.printString("BlockName", Block.Name);794});795796if (LVScope *Scope = LogicalVisitor->CurrentScope) {797StringRef LinkageName;798if (ObjDelegate)799ObjDelegate->getLinkageName(Block.getRelocationOffset(), Block.CodeOffset,800&LinkageName);801Scope->setLinkageName(LinkageName);802803if (options().getGeneralCollectRanges()) {804// Record converted segment::offset addressing for this scope.805LVAddress Addendum = Reader->getSymbolTableAddress(LinkageName);806LVAddress LowPC =807Reader->linearAddress(Block.Segment, Block.CodeOffset, Addendum);808LVAddress HighPC = LowPC + Block.CodeSize - 1;809Scope->addObject(LowPC, HighPC);810}811}812813return Error::success();814}815816// S_BPREL32817Error LVSymbolVisitor::visitKnownRecord(CVSymbol &Record,818BPRelativeSym &Local) {819LLVM_DEBUG({820printTypeIndex("Type", Local.Type);821W.printNumber("Offset", Local.Offset);822W.printString("VarName", Local.Name);823});824825if (LVSymbol *Symbol = LogicalVisitor->CurrentSymbol) {826Symbol->setName(Local.Name);827// From the MS_Symbol_Type.pdf documentation (S_BPREL32):828// This symbol specifies symbols that are allocated on the stack for a829// procedure. For C and C++, these include the actual function parameters830// and the local non-static variables of functions.831// However, the offset for 'this' comes as a negative value.832833// Symbol was created as 'variable'; determine its real kind.834Symbol->resetIsVariable();835836if (Local.Name == "this") {837Symbol->setIsParameter();838Symbol->setIsArtificial();839} else {840// Determine symbol kind.841bool(Local.Offset > 0) ? Symbol->setIsParameter()842: Symbol->setIsVariable();843}844845// Update correct debug information tag.846if (Symbol->getIsParameter())847Symbol->setTag(dwarf::DW_TAG_formal_parameter);848849LVElement *Element = LogicalVisitor->getElement(StreamTPI, Local.Type);850if (Element && Element->getIsScoped()) {851// We have a local type. Find its parent function.852LVScope *Parent = Symbol->getFunctionParent();853// The element representing the type has been already finalized. If854// the type is an aggregate type, its members have been already added.855// As the type is local, its level will be changed.856857// FIXME: Currently the algorithm used to scope lambda functions is858// incorrect. Before we allocate the type at this scope, check if is859// already allocated in other scope.860if (!Element->getParentScope()) {861Parent->addElement(Element);862Element->updateLevel(Parent);863}864}865Symbol->setType(Element);866}867868return Error::success();869}870871// S_REGREL32872Error LVSymbolVisitor::visitKnownRecord(CVSymbol &Record,873RegRelativeSym &Local) {874LLVM_DEBUG({875printTypeIndex("Type", Local.Type);876W.printNumber("Offset", Local.Offset);877W.printString("VarName", Local.Name);878});879880if (LVSymbol *Symbol = LogicalVisitor->CurrentSymbol) {881Symbol->setName(Local.Name);882883// Symbol was created as 'variable'; determine its real kind.884Symbol->resetIsVariable();885886// Check for the 'this' symbol.887if (Local.Name == "this") {888Symbol->setIsArtificial();889Symbol->setIsParameter();890} else {891// Determine symbol kind.892determineSymbolKind(Symbol, Local.Register);893}894895// Update correct debug information tag.896if (Symbol->getIsParameter())897Symbol->setTag(dwarf::DW_TAG_formal_parameter);898899LVElement *Element = LogicalVisitor->getElement(StreamTPI, Local.Type);900if (Element && Element->getIsScoped()) {901// We have a local type. Find its parent function.902LVScope *Parent = Symbol->getFunctionParent();903// The element representing the type has been already finalized. If904// the type is an aggregate type, its members have been already added.905// As the type is local, its level will be changed.906907// FIXME: Currently the algorithm used to scope lambda functions is908// incorrect. Before we allocate the type at this scope, check if is909// already allocated in other scope.910if (!Element->getParentScope()) {911Parent->addElement(Element);912Element->updateLevel(Parent);913}914}915Symbol->setType(Element);916}917918return Error::success();919}920921// S_BUILDINFO922Error LVSymbolVisitor::visitKnownRecord(CVSymbol &CVR,923BuildInfoSym &BuildInfo) {924LLVM_DEBUG({ printTypeIndex("BuildId", BuildInfo.BuildId); });925926CVType CVBuildType = Ids.getType(BuildInfo.BuildId);927if (Error Err = LogicalVisitor->finishVisitation(928CVBuildType, BuildInfo.BuildId, Reader->getCompileUnit()))929return Err;930931return Error::success();932}933934// S_COMPILE2935Error LVSymbolVisitor::visitKnownRecord(CVSymbol &Record,936Compile2Sym &Compile2) {937LLVM_DEBUG({938W.printEnum("Language", uint8_t(Compile2.getLanguage()),939getSourceLanguageNames());940W.printFlags("Flags", uint32_t(Compile2.getFlags()),941getCompileSym3FlagNames());942W.printEnum("Machine", unsigned(Compile2.Machine), getCPUTypeNames());943W.printString("VersionName", Compile2.Version);944});945946// MSVC generates the following sequence for a CodeView module:947// S_OBJNAME --> Set 'CurrentObjectName'.948// S_COMPILE2 --> Set the compile unit name using 'CurrentObjectName'.949// ...950// S_BUILDINFO --> Extract the source name.951//952// Clang generates the following sequence for a CodeView module:953// S_COMPILE2 --> Set the compile unit name to empty string.954// ...955// S_BUILDINFO --> Extract the source name.956//957// For both toolchains, update the compile unit name from S_BUILDINFO.958if (LVScope *Scope = LogicalVisitor->CurrentScope) {959// The name of the CU, was extracted from the 'BuildInfo' subsection.960Reader->setCompileUnitCPUType(Compile2.Machine);961Scope->setName(CurrentObjectName);962if (options().getAttributeProducer())963Scope->setProducer(Compile2.Version);964getReader().isSystemEntry(Scope, CurrentObjectName);965966// The line records in CodeView are recorded per Module ID. Update967// the relationship between the current CU and the Module ID.968Reader->addModule(Scope);969970// Updated the collected strings with their associated compile unit.971Shared->StringRecords.addFilenames(Reader->getCompileUnit());972}973974// Clear any previous ObjectName.975CurrentObjectName = "";976return Error::success();977}978979// S_COMPILE3980Error LVSymbolVisitor::visitKnownRecord(CVSymbol &Record,981Compile3Sym &Compile3) {982LLVM_DEBUG({983W.printEnum("Language", uint8_t(Compile3.getLanguage()),984getSourceLanguageNames());985W.printFlags("Flags", uint32_t(Compile3.getFlags()),986getCompileSym3FlagNames());987W.printEnum("Machine", unsigned(Compile3.Machine), getCPUTypeNames());988W.printString("VersionName", Compile3.Version);989});990991// MSVC generates the following sequence for a CodeView module:992// S_OBJNAME --> Set 'CurrentObjectName'.993// S_COMPILE3 --> Set the compile unit name using 'CurrentObjectName'.994// ...995// S_BUILDINFO --> Extract the source name.996//997// Clang generates the following sequence for a CodeView module:998// S_COMPILE3 --> Set the compile unit name to empty string.999// ...1000// S_BUILDINFO --> Extract the source name.1001//1002// For both toolchains, update the compile unit name from S_BUILDINFO.1003if (LVScope *Scope = LogicalVisitor->CurrentScope) {1004// The name of the CU, was extracted from the 'BuildInfo' subsection.1005Reader->setCompileUnitCPUType(Compile3.Machine);1006Scope->setName(CurrentObjectName);1007if (options().getAttributeProducer())1008Scope->setProducer(Compile3.Version);1009getReader().isSystemEntry(Scope, CurrentObjectName);10101011// The line records in CodeView are recorded per Module ID. Update1012// the relationship between the current CU and the Module ID.1013Reader->addModule(Scope);10141015// Updated the collected strings with their associated compile unit.1016Shared->StringRecords.addFilenames(Reader->getCompileUnit());1017}10181019// Clear any previous ObjectName.1020CurrentObjectName = "";1021return Error::success();1022}10231024// S_CONSTANT, S_MANCONSTANT1025Error LVSymbolVisitor::visitKnownRecord(CVSymbol &Record,1026ConstantSym &Constant) {1027LLVM_DEBUG({1028printTypeIndex("Type", Constant.Type);1029W.printNumber("Value", Constant.Value);1030W.printString("Name", Constant.Name);1031});10321033if (LVSymbol *Symbol = LogicalVisitor->CurrentSymbol) {1034Symbol->setName(Constant.Name);1035Symbol->setType(LogicalVisitor->getElement(StreamTPI, Constant.Type));1036Symbol->resetIncludeInPrint();1037}10381039return Error::success();1040}10411042// S_DEFRANGE_FRAMEPOINTER_REL_FULL_SCOPE1043Error LVSymbolVisitor::visitKnownRecord(1044CVSymbol &Record,1045DefRangeFramePointerRelFullScopeSym &DefRangeFramePointerRelFullScope) {1046// DefRanges don't have types, just registers and code offsets.1047LLVM_DEBUG({1048if (LocalSymbol)1049W.getOStream() << formatv("Symbol: {0}, ", LocalSymbol->getName());10501051W.printNumber("Offset", DefRangeFramePointerRelFullScope.Offset);1052});10531054if (LVSymbol *Symbol = LocalSymbol) {1055Symbol->setHasCodeViewLocation();1056LocalSymbol = nullptr;10571058// Add location debug location. Operands: [Offset, 0].1059dwarf::Attribute Attr =1060dwarf::Attribute(SymbolKind::S_DEFRANGE_FRAMEPOINTER_REL_FULL_SCOPE);10611062uint64_t Operand1 = DefRangeFramePointerRelFullScope.Offset;1063Symbol->addLocation(Attr, 0, 0, 0, 0);1064Symbol->addLocationOperands(LVSmall(Attr), {Operand1});1065}10661067return Error::success();1068}10691070// S_DEFRANGE_FRAMEPOINTER_REL1071Error LVSymbolVisitor::visitKnownRecord(1072CVSymbol &Record, DefRangeFramePointerRelSym &DefRangeFramePointerRel) {1073// DefRanges don't have types, just registers and code offsets.1074LLVM_DEBUG({1075if (LocalSymbol)1076W.getOStream() << formatv("Symbol: {0}, ", LocalSymbol->getName());10771078W.printNumber("Offset", DefRangeFramePointerRel.Hdr.Offset);1079printLocalVariableAddrRange(DefRangeFramePointerRel.Range,1080DefRangeFramePointerRel.getRelocationOffset());1081printLocalVariableAddrGap(DefRangeFramePointerRel.Gaps);1082});10831084// We are expecting the following sequence:1085// 128 | S_LOCAL [size = 20] `ParamBar`1086// ...1087// 148 | S_DEFRANGE_FRAMEPOINTER_REL [size = 16]1088if (LVSymbol *Symbol = LocalSymbol) {1089Symbol->setHasCodeViewLocation();1090LocalSymbol = nullptr;10911092// Add location debug location. Operands: [Offset, 0].1093dwarf::Attribute Attr =1094dwarf::Attribute(SymbolKind::S_DEFRANGE_FRAMEPOINTER_REL);1095uint64_t Operand1 = DefRangeFramePointerRel.Hdr.Offset;10961097LocalVariableAddrRange Range = DefRangeFramePointerRel.Range;1098LVAddress Address =1099Reader->linearAddress(Range.ISectStart, Range.OffsetStart);11001101Symbol->addLocation(Attr, Address, Address + Range.Range, 0, 0);1102Symbol->addLocationOperands(LVSmall(Attr), {Operand1});1103}11041105return Error::success();1106}11071108// S_DEFRANGE_REGISTER_REL1109Error LVSymbolVisitor::visitKnownRecord(1110CVSymbol &Record, DefRangeRegisterRelSym &DefRangeRegisterRel) {1111// DefRanges don't have types, just registers and code offsets.1112LLVM_DEBUG({1113if (LocalSymbol)1114W.getOStream() << formatv("Symbol: {0}, ", LocalSymbol->getName());11151116W.printBoolean("HasSpilledUDTMember",1117DefRangeRegisterRel.hasSpilledUDTMember());1118W.printNumber("OffsetInParent", DefRangeRegisterRel.offsetInParent());1119W.printNumber("BasePointerOffset",1120DefRangeRegisterRel.Hdr.BasePointerOffset);1121printLocalVariableAddrRange(DefRangeRegisterRel.Range,1122DefRangeRegisterRel.getRelocationOffset());1123printLocalVariableAddrGap(DefRangeRegisterRel.Gaps);1124});11251126if (LVSymbol *Symbol = LocalSymbol) {1127Symbol->setHasCodeViewLocation();1128LocalSymbol = nullptr;11291130// Add location debug location. Operands: [Register, Offset].1131dwarf::Attribute Attr =1132dwarf::Attribute(SymbolKind::S_DEFRANGE_REGISTER_REL);1133uint64_t Operand1 = DefRangeRegisterRel.Hdr.Register;1134uint64_t Operand2 = DefRangeRegisterRel.Hdr.BasePointerOffset;11351136LocalVariableAddrRange Range = DefRangeRegisterRel.Range;1137LVAddress Address =1138Reader->linearAddress(Range.ISectStart, Range.OffsetStart);11391140Symbol->addLocation(Attr, Address, Address + Range.Range, 0, 0);1141Symbol->addLocationOperands(LVSmall(Attr), {Operand1, Operand2});1142}11431144return Error::success();1145}11461147// S_DEFRANGE_REGISTER1148Error LVSymbolVisitor::visitKnownRecord(CVSymbol &Record,1149DefRangeRegisterSym &DefRangeRegister) {1150// DefRanges don't have types, just registers and code offsets.1151LLVM_DEBUG({1152if (LocalSymbol)1153W.getOStream() << formatv("Symbol: {0}, ", LocalSymbol->getName());11541155W.printEnum("Register", uint16_t(DefRangeRegister.Hdr.Register),1156getRegisterNames(Reader->getCompileUnitCPUType()));1157W.printNumber("MayHaveNoName", DefRangeRegister.Hdr.MayHaveNoName);1158printLocalVariableAddrRange(DefRangeRegister.Range,1159DefRangeRegister.getRelocationOffset());1160printLocalVariableAddrGap(DefRangeRegister.Gaps);1161});11621163if (LVSymbol *Symbol = LocalSymbol) {1164Symbol->setHasCodeViewLocation();1165LocalSymbol = nullptr;11661167// Add location debug location. Operands: [Register, 0].1168dwarf::Attribute Attr = dwarf::Attribute(SymbolKind::S_DEFRANGE_REGISTER);1169uint64_t Operand1 = DefRangeRegister.Hdr.Register;11701171LocalVariableAddrRange Range = DefRangeRegister.Range;1172LVAddress Address =1173Reader->linearAddress(Range.ISectStart, Range.OffsetStart);11741175Symbol->addLocation(Attr, Address, Address + Range.Range, 0, 0);1176Symbol->addLocationOperands(LVSmall(Attr), {Operand1});1177}11781179return Error::success();1180}11811182// S_DEFRANGE_SUBFIELD_REGISTER1183Error LVSymbolVisitor::visitKnownRecord(1184CVSymbol &Record, DefRangeSubfieldRegisterSym &DefRangeSubfieldRegister) {1185// DefRanges don't have types, just registers and code offsets.1186LLVM_DEBUG({1187if (LocalSymbol)1188W.getOStream() << formatv("Symbol: {0}, ", LocalSymbol->getName());11891190W.printEnum("Register", uint16_t(DefRangeSubfieldRegister.Hdr.Register),1191getRegisterNames(Reader->getCompileUnitCPUType()));1192W.printNumber("MayHaveNoName", DefRangeSubfieldRegister.Hdr.MayHaveNoName);1193W.printNumber("OffsetInParent",1194DefRangeSubfieldRegister.Hdr.OffsetInParent);1195printLocalVariableAddrRange(DefRangeSubfieldRegister.Range,1196DefRangeSubfieldRegister.getRelocationOffset());1197printLocalVariableAddrGap(DefRangeSubfieldRegister.Gaps);1198});11991200if (LVSymbol *Symbol = LocalSymbol) {1201Symbol->setHasCodeViewLocation();1202LocalSymbol = nullptr;12031204// Add location debug location. Operands: [Register, 0].1205dwarf::Attribute Attr =1206dwarf::Attribute(SymbolKind::S_DEFRANGE_SUBFIELD_REGISTER);1207uint64_t Operand1 = DefRangeSubfieldRegister.Hdr.Register;12081209LocalVariableAddrRange Range = DefRangeSubfieldRegister.Range;1210LVAddress Address =1211Reader->linearAddress(Range.ISectStart, Range.OffsetStart);12121213Symbol->addLocation(Attr, Address, Address + Range.Range, 0, 0);1214Symbol->addLocationOperands(LVSmall(Attr), {Operand1});1215}12161217return Error::success();1218}12191220// S_DEFRANGE_SUBFIELD1221Error LVSymbolVisitor::visitKnownRecord(CVSymbol &Record,1222DefRangeSubfieldSym &DefRangeSubfield) {1223// DefRanges don't have types, just registers and code offsets.1224LLVM_DEBUG({1225if (LocalSymbol)1226W.getOStream() << formatv("Symbol: {0}, ", LocalSymbol->getName());12271228if (ObjDelegate) {1229DebugStringTableSubsectionRef Strings = ObjDelegate->getStringTable();1230auto ExpectedProgram = Strings.getString(DefRangeSubfield.Program);1231if (!ExpectedProgram) {1232consumeError(ExpectedProgram.takeError());1233return llvm::make_error<CodeViewError>(1234"String table offset outside of bounds of String Table!");1235}1236W.printString("Program", *ExpectedProgram);1237}1238W.printNumber("OffsetInParent", DefRangeSubfield.OffsetInParent);1239printLocalVariableAddrRange(DefRangeSubfield.Range,1240DefRangeSubfield.getRelocationOffset());1241printLocalVariableAddrGap(DefRangeSubfield.Gaps);1242});12431244if (LVSymbol *Symbol = LocalSymbol) {1245Symbol->setHasCodeViewLocation();1246LocalSymbol = nullptr;12471248// Add location debug location. Operands: [Program, 0].1249dwarf::Attribute Attr = dwarf::Attribute(SymbolKind::S_DEFRANGE_SUBFIELD);1250uint64_t Operand1 = DefRangeSubfield.Program;12511252LocalVariableAddrRange Range = DefRangeSubfield.Range;1253LVAddress Address =1254Reader->linearAddress(Range.ISectStart, Range.OffsetStart);12551256Symbol->addLocation(Attr, Address, Address + Range.Range, 0, 0);1257Symbol->addLocationOperands(LVSmall(Attr), {Operand1, /*Operand2=*/0});1258}12591260return Error::success();1261}12621263// S_DEFRANGE1264Error LVSymbolVisitor::visitKnownRecord(CVSymbol &Record,1265DefRangeSym &DefRange) {1266// DefRanges don't have types, just registers and code offsets.1267LLVM_DEBUG({1268if (LocalSymbol)1269W.getOStream() << formatv("Symbol: {0}, ", LocalSymbol->getName());12701271if (ObjDelegate) {1272DebugStringTableSubsectionRef Strings = ObjDelegate->getStringTable();1273auto ExpectedProgram = Strings.getString(DefRange.Program);1274if (!ExpectedProgram) {1275consumeError(ExpectedProgram.takeError());1276return llvm::make_error<CodeViewError>(1277"String table offset outside of bounds of String Table!");1278}1279W.printString("Program", *ExpectedProgram);1280}1281printLocalVariableAddrRange(DefRange.Range, DefRange.getRelocationOffset());1282printLocalVariableAddrGap(DefRange.Gaps);1283});12841285if (LVSymbol *Symbol = LocalSymbol) {1286Symbol->setHasCodeViewLocation();1287LocalSymbol = nullptr;12881289// Add location debug location. Operands: [Program, 0].1290dwarf::Attribute Attr = dwarf::Attribute(SymbolKind::S_DEFRANGE);1291uint64_t Operand1 = DefRange.Program;12921293LocalVariableAddrRange Range = DefRange.Range;1294LVAddress Address =1295Reader->linearAddress(Range.ISectStart, Range.OffsetStart);12961297Symbol->addLocation(Attr, Address, Address + Range.Range, 0, 0);1298Symbol->addLocationOperands(LVSmall(Attr), {Operand1, /*Operand2=*/0});1299}13001301return Error::success();1302}13031304// S_FRAMEPROC1305Error LVSymbolVisitor::visitKnownRecord(CVSymbol &Record,1306FrameProcSym &FrameProc) {1307if (LVScope *Function = LogicalVisitor->getReaderScope()) {1308// S_FRAMEPROC contains extra information for the function described1309// by any of the previous generated records:1310// S_GPROC32, S_LPROC32, S_LPROC32_ID, S_GPROC32_ID.13111312// The generated sequence is:1313// S_GPROC32_ID ...1314// S_FRAMEPROC ...13151316// Collect additional inline flags for the current scope function.1317FrameProcedureOptions Flags = FrameProc.Flags;1318if (FrameProcedureOptions::MarkedInline ==1319(Flags & FrameProcedureOptions::MarkedInline))1320Function->setInlineCode(dwarf::DW_INL_declared_inlined);1321if (FrameProcedureOptions::Inlined ==1322(Flags & FrameProcedureOptions::Inlined))1323Function->setInlineCode(dwarf::DW_INL_inlined);13241325// To determine the symbol kind for any symbol declared in that function,1326// we can access the S_FRAMEPROC for the parent scope function. It contains1327// information about the local fp and param fp registers and compare with1328// the register in the S_REGREL32 to get a match.1329codeview::CPUType CPU = Reader->getCompileUnitCPUType();1330LocalFrameRegister = FrameProc.getLocalFramePtrReg(CPU);1331ParamFrameRegister = FrameProc.getParamFramePtrReg(CPU);1332}13331334return Error::success();1335}13361337// S_GDATA32, S_LDATA32, S_LMANDATA, S_GMANDATA1338Error LVSymbolVisitor::visitKnownRecord(CVSymbol &Record, DataSym &Data) {1339LLVM_DEBUG({1340printTypeIndex("Type", Data.Type);1341W.printString("DisplayName", Data.Name);1342});13431344if (LVSymbol *Symbol = LogicalVisitor->CurrentSymbol) {1345StringRef LinkageName;1346if (ObjDelegate)1347ObjDelegate->getLinkageName(Data.getRelocationOffset(), Data.DataOffset,1348&LinkageName);13491350Symbol->setName(Data.Name);1351Symbol->setLinkageName(LinkageName);13521353// The MSVC generates local data as initialization for aggregates. It1354// contains the address for an initialization function.1355// The symbols contains the '$initializer$' pattern. Allow them only if1356// the '--internal=system' option is given.1357// 0 | S_LDATA32 `Struct$initializer$`1358// type = 0x1040 (void ()*)1359if (getReader().isSystemEntry(Symbol) && !options().getAttributeSystem()) {1360Symbol->resetIncludeInPrint();1361return Error::success();1362}13631364if (LVScope *Namespace = Shared->NamespaceDeduction.get(Data.Name)) {1365// The variable is already at different scope. In order to reflect1366// the correct parent, move it to the namespace.1367if (Symbol->getParentScope()->removeElement(Symbol))1368Namespace->addElement(Symbol);1369}13701371Symbol->setType(LogicalVisitor->getElement(StreamTPI, Data.Type));1372if (Record.kind() == SymbolKind::S_GDATA32)1373Symbol->setIsExternal();1374}13751376return Error::success();1377}13781379// S_INLINESITE1380Error LVSymbolVisitor::visitKnownRecord(CVSymbol &Record,1381InlineSiteSym &InlineSite) {1382LLVM_DEBUG({ printTypeIndex("Inlinee", InlineSite.Inlinee); });13831384if (LVScope *InlinedFunction = LogicalVisitor->CurrentScope) {1385LVScope *AbstractFunction = Reader->createScopeFunction();1386AbstractFunction->setIsSubprogram();1387AbstractFunction->setTag(dwarf::DW_TAG_subprogram);1388AbstractFunction->setInlineCode(dwarf::DW_INL_inlined);1389AbstractFunction->setIsInlinedAbstract();1390InlinedFunction->setReference(AbstractFunction);13911392LogicalVisitor->startProcessArgumentList();1393// 'Inlinee' is a Type ID.1394CVType CVFunctionType = Ids.getType(InlineSite.Inlinee);1395if (Error Err = LogicalVisitor->finishVisitation(1396CVFunctionType, InlineSite.Inlinee, AbstractFunction))1397return Err;1398LogicalVisitor->stopProcessArgumentList();13991400// For inlined functions set the linkage name to be the same as1401// the name. It used to find their lines and ranges.1402StringRef Name = AbstractFunction->getName();1403InlinedFunction->setName(Name);1404InlinedFunction->setLinkageName(Name);14051406// Process annotation bytes to calculate code and line offsets.1407if (Error Err = LogicalVisitor->inlineSiteAnnotation(1408AbstractFunction, InlinedFunction, InlineSite))1409return Err;1410}14111412return Error::success();1413}14141415// S_LOCAL1416Error LVSymbolVisitor::visitKnownRecord(CVSymbol &Record, LocalSym &Local) {1417LLVM_DEBUG({1418printTypeIndex("Type", Local.Type);1419W.printFlags("Flags", uint16_t(Local.Flags), getLocalFlagNames());1420W.printString("VarName", Local.Name);1421});14221423if (LVSymbol *Symbol = LogicalVisitor->CurrentSymbol) {1424Symbol->setName(Local.Name);14251426// Symbol was created as 'variable'; determine its real kind.1427Symbol->resetIsVariable();14281429// Be sure the 'this' symbol is marked as 'compiler generated'.1430if (bool(Local.Flags & LocalSymFlags::IsCompilerGenerated) ||1431Local.Name == "this") {1432Symbol->setIsArtificial();1433Symbol->setIsParameter();1434} else {1435bool(Local.Flags & LocalSymFlags::IsParameter) ? Symbol->setIsParameter()1436: Symbol->setIsVariable();1437}14381439// Update correct debug information tag.1440if (Symbol->getIsParameter())1441Symbol->setTag(dwarf::DW_TAG_formal_parameter);14421443LVElement *Element = LogicalVisitor->getElement(StreamTPI, Local.Type);1444if (Element && Element->getIsScoped()) {1445// We have a local type. Find its parent function.1446LVScope *Parent = Symbol->getFunctionParent();1447// The element representing the type has been already finalized. If1448// the type is an aggregate type, its members have been already added.1449// As the type is local, its level will be changed.1450Parent->addElement(Element);1451Element->updateLevel(Parent);1452}1453Symbol->setType(Element);14541455// The CodeView records (S_DEFFRAME_*) describing debug location for1456// this symbol, do not have any direct reference to it. Those records1457// are emitted after this symbol. Record the current symbol.1458LocalSymbol = Symbol;1459}14601461return Error::success();1462}14631464// S_OBJNAME1465Error LVSymbolVisitor::visitKnownRecord(CVSymbol &Record, ObjNameSym &ObjName) {1466LLVM_DEBUG({1467W.printHex("Signature", ObjName.Signature);1468W.printString("ObjectName", ObjName.Name);1469});14701471CurrentObjectName = ObjName.Name;1472return Error::success();1473}14741475// S_GPROC32, S_LPROC32, S_LPROC32_ID, S_GPROC32_ID1476Error LVSymbolVisitor::visitKnownRecord(CVSymbol &Record, ProcSym &Proc) {1477if (InFunctionScope)1478return llvm::make_error<CodeViewError>("Visiting a ProcSym while inside "1479"function scope!");14801481InFunctionScope = true;14821483LLVM_DEBUG({1484printTypeIndex("FunctionType", Proc.FunctionType);1485W.printHex("Segment", Proc.Segment);1486W.printFlags("Flags", static_cast<uint8_t>(Proc.Flags),1487getProcSymFlagNames());1488W.printString("DisplayName", Proc.Name);1489});14901491// Clang and Microsoft generated different debug information records:1492// For functions definitions:1493// Clang: S_GPROC32 -> LF_FUNC_ID -> LF_PROCEDURE1494// Microsoft: S_GPROC32 -> LF_PROCEDURE14951496// For member function definition:1497// Clang: S_GPROC32 -> LF_MFUNC_ID -> LF_MFUNCTION1498// Microsoft: S_GPROC32 -> LF_MFUNCTION1499// In order to support both sequences, if we found LF_FUNCTION_ID, just1500// get the TypeIndex for LF_PROCEDURE.15011502// For the given test case, we have the sequence:1503// namespace NSP_local {1504// void foo_local() {1505// }1506// }1507//1508// 0x1000 | LF_STRING_ID String: NSP_local1509// 0x1002 | LF_PROCEDURE1510// return type = 0x0003 (void), # args = 0, param list = 0x10011511// calling conv = cdecl, options = None1512// 0x1003 | LF_FUNC_ID1513// name = foo_local, type = 0x1002, parent scope = 0x10001514// 0 | S_GPROC32_ID `NSP_local::foo_local`1515// type = `0x1003 (foo_local)`1516// 0x1004 | LF_STRING_ID String: suite1517// 0x1005 | LF_STRING_ID String: suite_local.cpp1518//1519// The LF_STRING_ID can hold different information:1520// 0x1000 - The enclosing namespace.1521// 0x1004 - The compile unit directory name.1522// 0x1005 - The compile unit name.1523//1524// Before deducting its scope, we need to evaluate its type and create any1525// associated namespaces.1526if (LVScope *Function = LogicalVisitor->CurrentScope) {1527StringRef LinkageName;1528if (ObjDelegate)1529ObjDelegate->getLinkageName(Proc.getRelocationOffset(), Proc.CodeOffset,1530&LinkageName);15311532// The line table can be accessed using the linkage name.1533Reader->addToSymbolTable(LinkageName, Function);1534Function->setName(Proc.Name);1535Function->setLinkageName(LinkageName);15361537if (options().getGeneralCollectRanges()) {1538// Record converted segment::offset addressing for this scope.1539LVAddress Addendum = Reader->getSymbolTableAddress(LinkageName);1540LVAddress LowPC =1541Reader->linearAddress(Proc.Segment, Proc.CodeOffset, Addendum);1542LVAddress HighPC = LowPC + Proc.CodeSize - 1;1543Function->addObject(LowPC, HighPC);15441545// If the scope is a function, add it to the public names.1546if ((options().getAttributePublics() || options().getPrintAnyLine()) &&1547!Function->getIsInlinedFunction())1548Reader->getCompileUnit()->addPublicName(Function, LowPC, HighPC);1549}15501551if (Function->getIsSystem() && !options().getAttributeSystem()) {1552Function->resetIncludeInPrint();1553return Error::success();1554}15551556TypeIndex TIFunctionType = Proc.FunctionType;1557if (TIFunctionType.isSimple())1558Function->setType(LogicalVisitor->getElement(StreamTPI, TIFunctionType));1559else {1560// We have to detect the correct stream, using the lexical parent1561// name, as there is not other obvious way to get the stream.1562// Normal function: LF_FUNC_ID (TPI)/(IPI)1563// LF_PROCEDURE (TPI)1564// Lambda function: LF_MFUNCTION (TPI)1565// Member function: LF_MFUNC_ID (TPI)/(IPI)15661567StringRef OuterComponent;1568std::tie(OuterComponent, std::ignore) = getInnerComponent(Proc.Name);1569TypeIndex TI = Shared->ForwardReferences.find(OuterComponent);15701571std::optional<CVType> CVFunctionType;1572auto GetRecordType = [&]() -> bool {1573CVFunctionType = Ids.tryGetType(TIFunctionType);1574if (!CVFunctionType)1575return false;15761577if (TI.isNoneType())1578// Normal function.1579if (CVFunctionType->kind() == LF_FUNC_ID)1580return true;15811582// Member function.1583return (CVFunctionType->kind() == LF_MFUNC_ID);1584};15851586// We can have a LF_FUNC_ID, LF_PROCEDURE or LF_MFUNCTION.1587if (!GetRecordType()) {1588CVFunctionType = Types.tryGetType(TIFunctionType);1589if (!CVFunctionType)1590return llvm::make_error<CodeViewError>("Invalid type index");1591}15921593if (Error Err = LogicalVisitor->finishVisitation(1594*CVFunctionType, TIFunctionType, Function))1595return Err;1596}15971598if (Record.kind() == SymbolKind::S_GPROC32 ||1599Record.kind() == SymbolKind::S_GPROC32_ID)1600Function->setIsExternal();16011602// We don't have a way to see if the symbol is compiler generated. Use1603// the linkage name, to detect `scalar deleting destructor' functions.1604std::string DemangledSymbol = demangle(LinkageName);1605if (DemangledSymbol.find("scalar deleting dtor") != std::string::npos) {1606Function->setIsArtificial();1607} else {1608// Clang generates global ctor and dtor names containing the substrings:1609// 'dynamic initializer for' and 'dynamic atexit destructor for'.1610if (DemangledSymbol.find("dynamic atexit destructor for") !=1611std::string::npos)1612Function->setIsArtificial();1613}1614}16151616return Error::success();1617}16181619// S_END1620Error LVSymbolVisitor::visitKnownRecord(CVSymbol &Record,1621ScopeEndSym &ScopeEnd) {1622InFunctionScope = false;1623return Error::success();1624}16251626// S_THUNK321627Error LVSymbolVisitor::visitKnownRecord(CVSymbol &Record, Thunk32Sym &Thunk) {1628if (InFunctionScope)1629return llvm::make_error<CodeViewError>("Visiting a Thunk32Sym while inside "1630"function scope!");16311632InFunctionScope = true;16331634LLVM_DEBUG({1635W.printHex("Segment", Thunk.Segment);1636W.printString("Name", Thunk.Name);1637});16381639if (LVScope *Function = LogicalVisitor->CurrentScope)1640Function->setName(Thunk.Name);16411642return Error::success();1643}16441645// S_UDT, S_COBOLUDT1646Error LVSymbolVisitor::visitKnownRecord(CVSymbol &Record, UDTSym &UDT) {1647LLVM_DEBUG({1648printTypeIndex("Type", UDT.Type);1649W.printString("UDTName", UDT.Name);1650});16511652if (LVType *Type = LogicalVisitor->CurrentType) {1653if (LVScope *Namespace = Shared->NamespaceDeduction.get(UDT.Name)) {1654if (Type->getParentScope()->removeElement(Type))1655Namespace->addElement(Type);1656}16571658Type->setName(UDT.Name);16591660// We have to determine if the typedef is a real C/C++ definition or is1661// the S_UDT record that describe all the user defined types.1662// 0 | S_UDT `Name` original type = 0x10091663// 0x1009 | LF_STRUCTURE `Name`1664// Ignore type definitions for RTTI types:1665// _s__RTTIBaseClassArray, _s__RTTIBaseClassDescriptor,1666// _s__RTTICompleteObjectLocator, _s__RTTIClassHierarchyDescriptor.1667if (getReader().isSystemEntry(Type))1668Type->resetIncludeInPrint();1669else {1670StringRef RecordName = getRecordName(Types, UDT.Type);1671if (UDT.Name == RecordName)1672Type->resetIncludeInPrint();1673Type->setType(LogicalVisitor->getElement(StreamTPI, UDT.Type));1674}1675}16761677return Error::success();1678}16791680// S_UNAMESPACE1681Error LVSymbolVisitor::visitKnownRecord(CVSymbol &Record,1682UsingNamespaceSym &UN) {1683LLVM_DEBUG({ W.printString("Namespace", UN.Name); });1684return Error::success();1685}16861687// S_ARMSWITCHTABLE1688Error LVSymbolVisitor::visitKnownRecord(CVSymbol &CVR,1689JumpTableSym &JumpTable) {1690LLVM_DEBUG({1691W.printHex("BaseOffset", JumpTable.BaseOffset);1692W.printNumber("BaseSegment", JumpTable.BaseSegment);1693W.printFlags("SwitchType", static_cast<uint16_t>(JumpTable.SwitchType),1694getJumpTableEntrySizeNames());1695W.printHex("BranchOffset", JumpTable.BranchOffset);1696W.printHex("TableOffset", JumpTable.TableOffset);1697W.printNumber("BranchSegment", JumpTable.BranchSegment);1698W.printNumber("TableSegment", JumpTable.TableSegment);1699W.printNumber("EntriesCount", JumpTable.EntriesCount);1700});1701return Error::success();1702}17031704// S_CALLERS, S_CALLEES, S_INLINEES1705Error LVSymbolVisitor::visitKnownRecord(CVSymbol &Record, CallerSym &Caller) {1706LLVM_DEBUG({1707llvm::StringRef FieldName;1708switch (Caller.getKind()) {1709case SymbolRecordKind::CallerSym:1710FieldName = "Callee";1711break;1712case SymbolRecordKind::CalleeSym:1713FieldName = "Caller";1714break;1715case SymbolRecordKind::InlineesSym:1716FieldName = "Inlinee";1717break;1718default:1719return llvm::make_error<CodeViewError>(1720"Unknown CV Record type for a CallerSym object!");1721}1722for (auto FuncID : Caller.Indices) {1723printTypeIndex(FieldName, FuncID);1724}1725});1726return Error::success();1727}17281729#undef DEBUG_TYPE1730#define DEBUG_TYPE "CodeViewLogicalVisitor"17311732//===----------------------------------------------------------------------===//1733// Logical visitor.1734//===----------------------------------------------------------------------===//1735LVLogicalVisitor::LVLogicalVisitor(LVCodeViewReader *Reader, ScopedPrinter &W,1736InputFile &Input)1737: Reader(Reader), W(W), Input(Input) {1738// The LogicalVisitor connects the CodeViewReader with the visitors that1739// traverse the types, symbols, etc. Do any initialization that is needed.1740Shared = std::make_shared<LVShared>(Reader, this);1741}17421743void LVLogicalVisitor::printTypeIndex(StringRef FieldName, TypeIndex TI,1744uint32_t StreamIdx) {1745codeview::printTypeIndex(W, FieldName, TI,1746StreamIdx == StreamTPI ? types() : ids());1747}17481749void LVLogicalVisitor::printTypeBegin(CVType &Record, TypeIndex TI,1750LVElement *Element, uint32_t StreamIdx) {1751W.getOStream() << "\n";1752W.startLine() << formatTypeLeafKind(Record.kind());1753W.getOStream() << " (" << HexNumber(TI.getIndex()) << ")";1754W.getOStream() << " {\n";1755W.indent();1756W.printEnum("TypeLeafKind", unsigned(Record.kind()), ArrayRef(LeafTypeNames));1757printTypeIndex("TI", TI, StreamIdx);1758W.startLine() << "Element: " << HexNumber(Element->getOffset()) << " "1759<< Element->getName() << "\n";1760}17611762void LVLogicalVisitor::printTypeEnd(CVType &Record) {1763W.unindent();1764W.startLine() << "}\n";1765}17661767void LVLogicalVisitor::printMemberBegin(CVMemberRecord &Record, TypeIndex TI,1768LVElement *Element,1769uint32_t StreamIdx) {1770W.getOStream() << "\n";1771W.startLine() << formatTypeLeafKind(Record.Kind);1772W.getOStream() << " (" << HexNumber(TI.getIndex()) << ")";1773W.getOStream() << " {\n";1774W.indent();1775W.printEnum("TypeLeafKind", unsigned(Record.Kind), ArrayRef(LeafTypeNames));1776printTypeIndex("TI", TI, StreamIdx);1777W.startLine() << "Element: " << HexNumber(Element->getOffset()) << " "1778<< Element->getName() << "\n";1779}17801781void LVLogicalVisitor::printMemberEnd(CVMemberRecord &Record) {1782W.unindent();1783W.startLine() << "}\n";1784}17851786Error LVLogicalVisitor::visitUnknownType(CVType &Record, TypeIndex TI) {1787LLVM_DEBUG({1788printTypeIndex("\nTI", TI, StreamTPI);1789W.printNumber("Length", uint32_t(Record.content().size()));1790});1791return Error::success();1792}17931794// LF_ARGLIST (TPI)1795Error LVLogicalVisitor::visitKnownRecord(CVType &Record, ArgListRecord &Args,1796TypeIndex TI, LVElement *Element) {1797ArrayRef<TypeIndex> Indices = Args.getIndices();1798uint32_t Size = Indices.size();1799LLVM_DEBUG({1800printTypeBegin(Record, TI, Element, StreamTPI);1801W.printNumber("NumArgs", Size);1802ListScope Arguments(W, "Arguments");1803for (uint32_t I = 0; I < Size; ++I)1804printTypeIndex("ArgType", Indices[I], StreamTPI);1805printTypeEnd(Record);1806});18071808LVScope *Function = static_cast<LVScope *>(Element);1809for (uint32_t Index = 0; Index < Size; ++Index) {1810TypeIndex ParameterType = Indices[Index];1811createParameter(ParameterType, StringRef(), Function);1812}18131814return Error::success();1815}18161817// LF_ARRAY (TPI)1818Error LVLogicalVisitor::visitKnownRecord(CVType &Record, ArrayRecord &AT,1819TypeIndex TI, LVElement *Element) {1820LLVM_DEBUG({1821printTypeBegin(Record, TI, Element, StreamTPI);1822printTypeIndex("ElementType", AT.getElementType(), StreamTPI);1823printTypeIndex("IndexType", AT.getIndexType(), StreamTPI);1824W.printNumber("SizeOf", AT.getSize());1825W.printString("Name", AT.getName());1826printTypeEnd(Record);1827});18281829if (Element->getIsFinalized())1830return Error::success();1831Element->setIsFinalized();18321833LVScopeArray *Array = static_cast<LVScopeArray *>(Element);1834if (!Array)1835return Error::success();18361837Reader->getCompileUnit()->addElement(Array);1838TypeIndex TIElementType = AT.getElementType();18391840LVType *PrevSubrange = nullptr;1841LazyRandomTypeCollection &Types = types();18421843// As the logical view is modeled on DWARF, for each dimension we have to1844// create a DW_TAG_subrange_type, with dimension size.1845// The subrange type can be: unsigned __int32 or unsigned __int64.1846auto AddSubrangeType = [&](ArrayRecord &AR) {1847LVType *Subrange = Reader->createTypeSubrange();1848Subrange->setTag(dwarf::DW_TAG_subrange_type);1849Subrange->setType(getElement(StreamTPI, AR.getIndexType()));1850Subrange->setCount(AR.getSize());1851Subrange->setOffset(1852TIElementType.isSimple()1853? (uint32_t)(TypeLeafKind)TIElementType.getSimpleKind()1854: TIElementType.getIndex());1855Array->addElement(Subrange);18561857if (PrevSubrange)1858if (int64_t Count = Subrange->getCount())1859PrevSubrange->setCount(PrevSubrange->getCount() / Count);1860PrevSubrange = Subrange;1861};18621863// Preserve the original TypeIndex; it would be updated in the case of:1864// - The array type contains qualifiers.1865// - In multidimensional arrays, the last LF_ARRAY entry contains the type.1866TypeIndex TIArrayType;18671868// For each dimension in the array, there is a LF_ARRAY entry. The last1869// entry contains the array type, which can be a LF_MODIFIER in the case1870// of the type being modified by a qualifier (const, etc).1871ArrayRecord AR(AT);1872CVType CVEntry = Record;1873while (CVEntry.kind() == LF_ARRAY) {1874// Create the subrange information, required by the logical view. Once1875// the array has been processed, the dimension sizes will updated, as1876// the sizes are a progression. For instance:1877// sizeof(int) = 41878// int Array[2]; Sizes: 8 Dim: 8 / 4 -> [2]1879// int Array[2][3]; Sizes: 24, 12 Dim: 24 / 12 -> [2]1880// Dim: 12 / 4 -> [3]1881// int Array[2][3][4]; sizes: 96, 48, 16 Dim: 96 / 48 -> [2]1882// Dim: 48 / 16 -> [3]1883// Dim: 16 / 4 -> [4]1884AddSubrangeType(AR);1885TIArrayType = TIElementType;18861887// The current ElementType can be a modifier, in which case we need to1888// get the type being modified.1889// If TypeIndex is not a simple type, check if we have a qualified type.1890if (!TIElementType.isSimple()) {1891CVType CVElementType = Types.getType(TIElementType);1892if (CVElementType.kind() == LF_MODIFIER) {1893LVElement *QualifiedType =1894Shared->TypeRecords.find(StreamTPI, TIElementType);1895if (Error Err =1896finishVisitation(CVElementType, TIElementType, QualifiedType))1897return Err;1898// Get the TypeIndex of the type that the LF_MODIFIER modifies.1899TIElementType = getModifiedType(CVElementType);1900}1901}1902// Ends the traversal, as we have reached a simple type (int, char, etc).1903if (TIElementType.isSimple())1904break;19051906// Read next dimension linked entry, if any.1907CVEntry = Types.getType(TIElementType);1908if (Error Err = TypeDeserializer::deserializeAs(1909const_cast<CVType &>(CVEntry), AR)) {1910consumeError(std::move(Err));1911break;1912}1913TIElementType = AR.getElementType();1914// NOTE: The typeindex has a value of: 0x0280.00001915getTrueType(TIElementType);1916}19171918Array->setName(AT.getName());1919TIArrayType = Shared->ForwardReferences.remap(TIArrayType);1920Array->setType(getElement(StreamTPI, TIArrayType));19211922if (PrevSubrange)1923// In the case of an aggregate type (class, struct, union, interface),1924// get the aggregate size. As the original record is pointing to its1925// reference, we have to update it.1926if (uint64_t Size =1927isAggregate(CVEntry)1928? getSizeInBytesForTypeRecord(Types.getType(TIArrayType))1929: getSizeInBytesForTypeIndex(TIElementType))1930PrevSubrange->setCount(PrevSubrange->getCount() / Size);19311932return Error::success();1933}19341935// LF_BITFIELD (TPI)1936Error LVLogicalVisitor::visitKnownRecord(CVType &Record, BitFieldRecord &BF,1937TypeIndex TI, LVElement *Element) {1938LLVM_DEBUG({1939printTypeBegin(Record, TI, Element, StreamTPI);1940printTypeIndex("Type", TI, StreamTPI);1941W.printNumber("BitSize", BF.getBitSize());1942W.printNumber("BitOffset", BF.getBitOffset());1943printTypeEnd(Record);1944});19451946Element->setType(getElement(StreamTPI, BF.getType()));1947Element->setBitSize(BF.getBitSize());1948return Error::success();1949}19501951// LF_BUILDINFO (TPI)/(IPI)1952Error LVLogicalVisitor::visitKnownRecord(CVType &Record, BuildInfoRecord &BI,1953TypeIndex TI, LVElement *Element) {1954LLVM_DEBUG({1955printTypeBegin(Record, TI, Element, StreamIPI);1956W.printNumber("NumArgs", static_cast<uint32_t>(BI.getArgs().size()));1957ListScope Arguments(W, "Arguments");1958for (TypeIndex Arg : BI.getArgs())1959printTypeIndex("ArgType", Arg, StreamIPI);1960printTypeEnd(Record);1961});19621963// The given 'Element' refers to the current compilation unit.1964// All the args are references into the TPI/IPI stream.1965TypeIndex TIName = BI.getArgs()[BuildInfoRecord::BuildInfoArg::SourceFile];1966std::string Name = std::string(ids().getTypeName(TIName));19671968// There are cases where LF_BUILDINFO fields are empty.1969if (!Name.empty())1970Element->setName(Name);19711972return Error::success();1973}19741975// LF_CLASS, LF_STRUCTURE, LF_INTERFACE (TPI)1976Error LVLogicalVisitor::visitKnownRecord(CVType &Record, ClassRecord &Class,1977TypeIndex TI, LVElement *Element) {1978LLVM_DEBUG({1979printTypeBegin(Record, TI, Element, StreamTPI);1980W.printNumber("MemberCount", Class.getMemberCount());1981printTypeIndex("FieldList", Class.getFieldList(), StreamTPI);1982printTypeIndex("DerivedFrom", Class.getDerivationList(), StreamTPI);1983printTypeIndex("VShape", Class.getVTableShape(), StreamTPI);1984W.printNumber("SizeOf", Class.getSize());1985W.printString("Name", Class.getName());1986if (Class.hasUniqueName())1987W.printString("UniqueName", Class.getUniqueName());1988printTypeEnd(Record);1989});19901991if (Element->getIsFinalized())1992return Error::success();1993Element->setIsFinalized();19941995LVScopeAggregate *Scope = static_cast<LVScopeAggregate *>(Element);1996if (!Scope)1997return Error::success();19981999Scope->setName(Class.getName());2000if (Class.hasUniqueName())2001Scope->setLinkageName(Class.getUniqueName());20022003if (Class.isNested()) {2004Scope->setIsNested();2005createParents(Class.getName(), Scope);2006}20072008if (Class.isScoped())2009Scope->setIsScoped();20102011// Nested types will be added to their parents at creation. The forward2012// references are only processed to finish the referenced element creation.2013if (!(Class.isNested() || Class.isScoped())) {2014if (LVScope *Namespace = Shared->NamespaceDeduction.get(Class.getName()))2015Namespace->addElement(Scope);2016else2017Reader->getCompileUnit()->addElement(Scope);2018}20192020LazyRandomTypeCollection &Types = types();2021TypeIndex TIFieldList = Class.getFieldList();2022if (TIFieldList.isNoneType()) {2023TypeIndex ForwardType = Shared->ForwardReferences.find(Class.getName());2024if (!ForwardType.isNoneType()) {2025CVType CVReference = Types.getType(ForwardType);2026TypeRecordKind RK = static_cast<TypeRecordKind>(CVReference.kind());2027ClassRecord ReferenceRecord(RK);2028if (Error Err = TypeDeserializer::deserializeAs(2029const_cast<CVType &>(CVReference), ReferenceRecord))2030return Err;2031TIFieldList = ReferenceRecord.getFieldList();2032}2033}20342035if (!TIFieldList.isNoneType()) {2036// Pass down the TypeIndex 'TI' for the aggregate containing the field list.2037CVType CVFieldList = Types.getType(TIFieldList);2038if (Error Err = finishVisitation(CVFieldList, TI, Scope))2039return Err;2040}20412042return Error::success();2043}20442045// LF_ENUM (TPI)2046Error LVLogicalVisitor::visitKnownRecord(CVType &Record, EnumRecord &Enum,2047TypeIndex TI, LVElement *Element) {2048LLVM_DEBUG({2049printTypeBegin(Record, TI, Element, StreamTPI);2050W.printNumber("NumEnumerators", Enum.getMemberCount());2051printTypeIndex("UnderlyingType", Enum.getUnderlyingType(), StreamTPI);2052printTypeIndex("FieldListType", Enum.getFieldList(), StreamTPI);2053W.printString("Name", Enum.getName());2054printTypeEnd(Record);2055});20562057LVScopeEnumeration *Scope = static_cast<LVScopeEnumeration *>(Element);2058if (!Scope)2059return Error::success();20602061if (Scope->getIsFinalized())2062return Error::success();2063Scope->setIsFinalized();20642065// Set the name, as in the case of nested, it would determine the relation2066// to any potential parent, via the LF_NESTTYPE record.2067Scope->setName(Enum.getName());2068if (Enum.hasUniqueName())2069Scope->setLinkageName(Enum.getUniqueName());20702071Scope->setType(getElement(StreamTPI, Enum.getUnderlyingType()));20722073if (Enum.isNested()) {2074Scope->setIsNested();2075createParents(Enum.getName(), Scope);2076}20772078if (Enum.isScoped()) {2079Scope->setIsScoped();2080Scope->setIsEnumClass();2081}20822083// Nested types will be added to their parents at creation.2084if (!(Enum.isNested() || Enum.isScoped())) {2085if (LVScope *Namespace = Shared->NamespaceDeduction.get(Enum.getName()))2086Namespace->addElement(Scope);2087else2088Reader->getCompileUnit()->addElement(Scope);2089}20902091TypeIndex TIFieldList = Enum.getFieldList();2092if (!TIFieldList.isNoneType()) {2093LazyRandomTypeCollection &Types = types();2094CVType CVFieldList = Types.getType(TIFieldList);2095if (Error Err = finishVisitation(CVFieldList, TIFieldList, Scope))2096return Err;2097}20982099return Error::success();2100}21012102// LF_FIELDLIST (TPI)2103Error LVLogicalVisitor::visitKnownRecord(CVType &Record,2104FieldListRecord &FieldList,2105TypeIndex TI, LVElement *Element) {2106LLVM_DEBUG({2107printTypeBegin(Record, TI, Element, StreamTPI);2108printTypeEnd(Record);2109});21102111if (Error Err = visitFieldListMemberStream(TI, Element, FieldList.Data))2112return Err;21132114return Error::success();2115}21162117// LF_FUNC_ID (TPI)/(IPI)2118Error LVLogicalVisitor::visitKnownRecord(CVType &Record, FuncIdRecord &Func,2119TypeIndex TI, LVElement *Element) {2120// ParentScope and FunctionType are references into the TPI stream.2121LLVM_DEBUG({2122printTypeBegin(Record, TI, Element, StreamIPI);2123printTypeIndex("ParentScope", Func.getParentScope(), StreamTPI);2124printTypeIndex("FunctionType", Func.getFunctionType(), StreamTPI);2125W.printString("Name", Func.getName());2126printTypeEnd(Record);2127});21282129// The TypeIndex (LF_PROCEDURE) returned by 'getFunctionType' is the2130// function propotype, we need to use the function definition.2131if (LVScope *FunctionDcl = static_cast<LVScope *>(Element)) {2132// For inlined functions, the inlined instance has been already processed2133// (all its information is contained in the Symbols section).2134// 'Element' points to the created 'abstract' (out-of-line) function.2135// Use the parent scope information to allocate it to the correct scope.2136LazyRandomTypeCollection &Types = types();2137TypeIndex TIParent = Func.getParentScope();2138if (FunctionDcl->getIsInlinedAbstract()) {2139FunctionDcl->setName(Func.getName());2140if (TIParent.isNoneType())2141Reader->getCompileUnit()->addElement(FunctionDcl);2142}21432144if (!TIParent.isNoneType()) {2145CVType CVParentScope = ids().getType(TIParent);2146if (Error Err = finishVisitation(CVParentScope, TIParent, FunctionDcl))2147return Err;2148}21492150TypeIndex TIFunctionType = Func.getFunctionType();2151CVType CVFunctionType = Types.getType(TIFunctionType);2152if (Error Err =2153finishVisitation(CVFunctionType, TIFunctionType, FunctionDcl))2154return Err;21552156FunctionDcl->setIsFinalized();2157}21582159return Error::success();2160}21612162// LF_LABEL (TPI)2163Error LVLogicalVisitor::visitKnownRecord(CVType &Record, LabelRecord &LR,2164TypeIndex TI, LVElement *Element) {2165LLVM_DEBUG({2166printTypeBegin(Record, TI, Element, StreamTPI);2167printTypeEnd(Record);2168});2169return Error::success();2170}21712172// LF_MFUNC_ID (TPI)/(IPI)2173Error LVLogicalVisitor::visitKnownRecord(CVType &Record, MemberFuncIdRecord &Id,2174TypeIndex TI, LVElement *Element) {2175// ClassType and FunctionType are references into the TPI stream.2176LLVM_DEBUG({2177printTypeBegin(Record, TI, Element, StreamIPI);2178printTypeIndex("ClassType", Id.getClassType(), StreamTPI);2179printTypeIndex("FunctionType", Id.getFunctionType(), StreamTPI);2180W.printString("Name", Id.getName());2181printTypeEnd(Record);2182});21832184LVScope *FunctionDcl = static_cast<LVScope *>(Element);2185if (FunctionDcl->getIsInlinedAbstract()) {2186// For inlined functions, the inlined instance has been already processed2187// (all its information is contained in the Symbols section).2188// 'Element' points to the created 'abstract' (out-of-line) function.2189// Use the parent scope information to allocate it to the correct scope.2190if (LVScope *Class = static_cast<LVScope *>(2191Shared->TypeRecords.find(StreamTPI, Id.getClassType())))2192Class->addElement(FunctionDcl);2193}21942195TypeIndex TIFunctionType = Id.getFunctionType();2196CVType CVFunction = types().getType(TIFunctionType);2197if (Error Err = finishVisitation(CVFunction, TIFunctionType, Element))2198return Err;21992200return Error::success();2201}22022203// LF_MFUNCTION (TPI)2204Error LVLogicalVisitor::visitKnownRecord(CVType &Record,2205MemberFunctionRecord &MF, TypeIndex TI,2206LVElement *Element) {2207LLVM_DEBUG({2208printTypeBegin(Record, TI, Element, StreamTPI);2209printTypeIndex("ReturnType", MF.getReturnType(), StreamTPI);2210printTypeIndex("ClassType", MF.getClassType(), StreamTPI);2211printTypeIndex("ThisType", MF.getThisType(), StreamTPI);2212W.printNumber("NumParameters", MF.getParameterCount());2213printTypeIndex("ArgListType", MF.getArgumentList(), StreamTPI);2214W.printNumber("ThisAdjustment", MF.getThisPointerAdjustment());2215printTypeEnd(Record);2216});22172218if (LVScope *MemberFunction = static_cast<LVScope *>(Element)) {2219LVElement *Class = getElement(StreamTPI, MF.getClassType());22202221MemberFunction->setIsFinalized();2222MemberFunction->setType(getElement(StreamTPI, MF.getReturnType()));2223MemberFunction->setOffset(TI.getIndex());2224MemberFunction->setOffsetFromTypeIndex();22252226if (ProcessArgumentList) {2227ProcessArgumentList = false;22282229if (!MemberFunction->getIsStatic()) {2230LVElement *ThisPointer = getElement(StreamTPI, MF.getThisType());2231// When creating the 'this' pointer, check if it points to a reference.2232ThisPointer->setType(Class);2233LVSymbol *This =2234createParameter(ThisPointer, StringRef(), MemberFunction);2235This->setIsArtificial();2236}22372238// Create formal parameters.2239LazyRandomTypeCollection &Types = types();2240CVType CVArguments = Types.getType(MF.getArgumentList());2241if (Error Err = finishVisitation(CVArguments, MF.getArgumentList(),2242MemberFunction))2243return Err;2244}2245}22462247return Error::success();2248}22492250// LF_METHODLIST (TPI)2251Error LVLogicalVisitor::visitKnownRecord(CVType &Record,2252MethodOverloadListRecord &Overloads,2253TypeIndex TI, LVElement *Element) {2254LLVM_DEBUG({2255printTypeBegin(Record, TI, Element, StreamTPI);2256printTypeEnd(Record);2257});22582259for (OneMethodRecord &Method : Overloads.Methods) {2260CVMemberRecord Record;2261Record.Kind = LF_METHOD;2262Method.Name = OverloadedMethodName;2263if (Error Err = visitKnownMember(Record, Method, TI, Element))2264return Err;2265}22662267return Error::success();2268}22692270// LF_MODIFIER (TPI)2271Error LVLogicalVisitor::visitKnownRecord(CVType &Record, ModifierRecord &Mod,2272TypeIndex TI, LVElement *Element) {2273LLVM_DEBUG({2274printTypeBegin(Record, TI, Element, StreamTPI);2275printTypeIndex("ModifiedType", Mod.getModifiedType(), StreamTPI);2276printTypeEnd(Record);2277});22782279// Create the modified type, which will be attached to the type(s) that2280// contains the modifiers.2281LVElement *ModifiedType = getElement(StreamTPI, Mod.getModifiedType());22822283// At this point the types recording the qualifiers do not have a2284// scope parent. They must be assigned to the current compile unit.2285LVScopeCompileUnit *CompileUnit = Reader->getCompileUnit();22862287// The incoming element does not have a defined kind. Use the given2288// modifiers to complete its type. A type can have more than one modifier;2289// in that case, we have to create an extra type to have the other modifier.2290LVType *LastLink = static_cast<LVType *>(Element);2291if (!LastLink->getParentScope())2292CompileUnit->addElement(LastLink);22932294bool SeenModifier = false;2295uint16_t Mods = static_cast<uint16_t>(Mod.getModifiers());2296if (Mods & uint16_t(ModifierOptions::Const)) {2297SeenModifier = true;2298LastLink->setTag(dwarf::DW_TAG_const_type);2299LastLink->setIsConst();2300LastLink->setName("const");2301}2302if (Mods & uint16_t(ModifierOptions::Volatile)) {2303if (SeenModifier) {2304LVType *Volatile = Reader->createType();2305Volatile->setIsModifier();2306LastLink->setType(Volatile);2307LastLink = Volatile;2308CompileUnit->addElement(LastLink);2309}2310LastLink->setTag(dwarf::DW_TAG_volatile_type);2311LastLink->setIsVolatile();2312LastLink->setName("volatile");2313}2314if (Mods & uint16_t(ModifierOptions::Unaligned)) {2315if (SeenModifier) {2316LVType *Unaligned = Reader->createType();2317Unaligned->setIsModifier();2318LastLink->setType(Unaligned);2319LastLink = Unaligned;2320CompileUnit->addElement(LastLink);2321}2322LastLink->setTag(dwarf::DW_TAG_unaligned);2323LastLink->setIsUnaligned();2324LastLink->setName("unaligned");2325}23262327LastLink->setType(ModifiedType);2328return Error::success();2329}23302331// LF_POINTER (TPI)2332Error LVLogicalVisitor::visitKnownRecord(CVType &Record, PointerRecord &Ptr,2333TypeIndex TI, LVElement *Element) {2334LLVM_DEBUG({2335printTypeBegin(Record, TI, Element, StreamTPI);2336printTypeIndex("PointeeType", Ptr.getReferentType(), StreamTPI);2337W.printNumber("IsFlat", Ptr.isFlat());2338W.printNumber("IsConst", Ptr.isConst());2339W.printNumber("IsVolatile", Ptr.isVolatile());2340W.printNumber("IsUnaligned", Ptr.isUnaligned());2341W.printNumber("IsRestrict", Ptr.isRestrict());2342W.printNumber("IsThisPtr&", Ptr.isLValueReferenceThisPtr());2343W.printNumber("IsThisPtr&&", Ptr.isRValueReferenceThisPtr());2344W.printNumber("SizeOf", Ptr.getSize());23452346if (Ptr.isPointerToMember()) {2347const MemberPointerInfo &MI = Ptr.getMemberInfo();2348printTypeIndex("ClassType", MI.getContainingType(), StreamTPI);2349}2350printTypeEnd(Record);2351});23522353// Find the pointed-to type.2354LVType *Pointer = static_cast<LVType *>(Element);2355LVElement *Pointee = nullptr;23562357PointerMode Mode = Ptr.getMode();2358Pointee = Ptr.isPointerToMember()2359? Shared->TypeRecords.find(StreamTPI, Ptr.getReferentType())2360: getElement(StreamTPI, Ptr.getReferentType());23612362// At this point the types recording the qualifiers do not have a2363// scope parent. They must be assigned to the current compile unit.2364LVScopeCompileUnit *CompileUnit = Reader->getCompileUnit();23652366// Order for the different modifiers:2367// <restrict> <pointer, Reference, ValueReference> <const, volatile>2368// Const and volatile already processed.2369bool SeenModifier = false;2370LVType *LastLink = Pointer;2371if (!LastLink->getParentScope())2372CompileUnit->addElement(LastLink);23732374if (Ptr.isRestrict()) {2375SeenModifier = true;2376LVType *Restrict = Reader->createType();2377Restrict->setTag(dwarf::DW_TAG_restrict_type);2378Restrict->setIsRestrict();2379Restrict->setName("restrict");2380LastLink->setType(Restrict);2381LastLink = Restrict;2382CompileUnit->addElement(LastLink);2383}2384if (Mode == PointerMode::LValueReference) {2385if (SeenModifier) {2386LVType *LReference = Reader->createType();2387LReference->setIsModifier();2388LastLink->setType(LReference);2389LastLink = LReference;2390CompileUnit->addElement(LastLink);2391}2392LastLink->setTag(dwarf::DW_TAG_reference_type);2393LastLink->setIsReference();2394LastLink->setName("&");2395}2396if (Mode == PointerMode::RValueReference) {2397if (SeenModifier) {2398LVType *RReference = Reader->createType();2399RReference->setIsModifier();2400LastLink->setType(RReference);2401LastLink = RReference;2402CompileUnit->addElement(LastLink);2403}2404LastLink->setTag(dwarf::DW_TAG_rvalue_reference_type);2405LastLink->setIsRvalueReference();2406LastLink->setName("&&");2407}24082409// When creating the pointer, check if it points to a reference.2410LastLink->setType(Pointee);2411return Error::success();2412}24132414// LF_PROCEDURE (TPI)2415Error LVLogicalVisitor::visitKnownRecord(CVType &Record, ProcedureRecord &Proc,2416TypeIndex TI, LVElement *Element) {2417LLVM_DEBUG({2418printTypeBegin(Record, TI, Element, StreamTPI);2419printTypeIndex("ReturnType", Proc.getReturnType(), StreamTPI);2420W.printNumber("NumParameters", Proc.getParameterCount());2421printTypeIndex("ArgListType", Proc.getArgumentList(), StreamTPI);2422printTypeEnd(Record);2423});24242425// There is no need to traverse the argument list, as the CodeView format2426// declares the parameters as a 'S_LOCAL' symbol tagged as parameter.2427// Only process parameters when dealing with inline functions.2428if (LVScope *FunctionDcl = static_cast<LVScope *>(Element)) {2429FunctionDcl->setType(getElement(StreamTPI, Proc.getReturnType()));24302431if (ProcessArgumentList) {2432ProcessArgumentList = false;2433// Create formal parameters.2434LazyRandomTypeCollection &Types = types();2435CVType CVArguments = Types.getType(Proc.getArgumentList());2436if (Error Err = finishVisitation(CVArguments, Proc.getArgumentList(),2437FunctionDcl))2438return Err;2439}2440}24412442return Error::success();2443}24442445// LF_UNION (TPI)2446Error LVLogicalVisitor::visitKnownRecord(CVType &Record, UnionRecord &Union,2447TypeIndex TI, LVElement *Element) {2448LLVM_DEBUG({2449printTypeBegin(Record, TI, Element, StreamTPI);2450W.printNumber("MemberCount", Union.getMemberCount());2451printTypeIndex("FieldList", Union.getFieldList(), StreamTPI);2452W.printNumber("SizeOf", Union.getSize());2453W.printString("Name", Union.getName());2454if (Union.hasUniqueName())2455W.printString("UniqueName", Union.getUniqueName());2456printTypeEnd(Record);2457});24582459LVScopeAggregate *Scope = static_cast<LVScopeAggregate *>(Element);2460if (!Scope)2461return Error::success();24622463if (Scope->getIsFinalized())2464return Error::success();2465Scope->setIsFinalized();24662467Scope->setName(Union.getName());2468if (Union.hasUniqueName())2469Scope->setLinkageName(Union.getUniqueName());24702471if (Union.isNested()) {2472Scope->setIsNested();2473createParents(Union.getName(), Scope);2474} else {2475if (LVScope *Namespace = Shared->NamespaceDeduction.get(Union.getName()))2476Namespace->addElement(Scope);2477else2478Reader->getCompileUnit()->addElement(Scope);2479}24802481if (!Union.getFieldList().isNoneType()) {2482LazyRandomTypeCollection &Types = types();2483// Pass down the TypeIndex 'TI' for the aggregate containing the field list.2484CVType CVFieldList = Types.getType(Union.getFieldList());2485if (Error Err = finishVisitation(CVFieldList, TI, Scope))2486return Err;2487}24882489return Error::success();2490}24912492// LF_TYPESERVER2 (TPI)2493Error LVLogicalVisitor::visitKnownRecord(CVType &Record, TypeServer2Record &TS,2494TypeIndex TI, LVElement *Element) {2495LLVM_DEBUG({2496printTypeBegin(Record, TI, Element, StreamTPI);2497W.printString("Guid", formatv("{0}", TS.getGuid()).str());2498W.printNumber("Age", TS.getAge());2499W.printString("Name", TS.getName());2500printTypeEnd(Record);2501});2502return Error::success();2503}25042505// LF_VFTABLE (TPI)2506Error LVLogicalVisitor::visitKnownRecord(CVType &Record, VFTableRecord &VFT,2507TypeIndex TI, LVElement *Element) {2508LLVM_DEBUG({2509printTypeBegin(Record, TI, Element, StreamTPI);2510printTypeIndex("CompleteClass", VFT.getCompleteClass(), StreamTPI);2511printTypeIndex("OverriddenVFTable", VFT.getOverriddenVTable(), StreamTPI);2512W.printHex("VFPtrOffset", VFT.getVFPtrOffset());2513W.printString("VFTableName", VFT.getName());2514for (const StringRef &N : VFT.getMethodNames())2515W.printString("MethodName", N);2516printTypeEnd(Record);2517});2518return Error::success();2519}25202521// LF_VTSHAPE (TPI)2522Error LVLogicalVisitor::visitKnownRecord(CVType &Record,2523VFTableShapeRecord &Shape,2524TypeIndex TI, LVElement *Element) {2525LLVM_DEBUG({2526printTypeBegin(Record, TI, Element, StreamTPI);2527W.printNumber("VFEntryCount", Shape.getEntryCount());2528printTypeEnd(Record);2529});2530return Error::success();2531}25322533// LF_SUBSTR_LIST (TPI)/(IPI)2534Error LVLogicalVisitor::visitKnownRecord(CVType &Record,2535StringListRecord &Strings,2536TypeIndex TI, LVElement *Element) {2537// All the indices are references into the TPI/IPI stream.2538LLVM_DEBUG({2539printTypeBegin(Record, TI, Element, StreamIPI);2540ArrayRef<TypeIndex> Indices = Strings.getIndices();2541uint32_t Size = Indices.size();2542W.printNumber("NumStrings", Size);2543ListScope Arguments(W, "Strings");2544for (uint32_t I = 0; I < Size; ++I)2545printTypeIndex("String", Indices[I], StreamIPI);2546printTypeEnd(Record);2547});2548return Error::success();2549}25502551// LF_STRING_ID (TPI)/(IPI)2552Error LVLogicalVisitor::visitKnownRecord(CVType &Record, StringIdRecord &String,2553TypeIndex TI, LVElement *Element) {2554// All args are references into the TPI/IPI stream.2555LLVM_DEBUG({2556printTypeIndex("\nTI", TI, StreamIPI);2557printTypeIndex("Id", String.getId(), StreamIPI);2558W.printString("StringData", String.getString());2559});25602561if (LVScope *Namespace = Shared->NamespaceDeduction.get(2562String.getString(), /*CheckScope=*/false)) {2563// The function is already at different scope. In order to reflect2564// the correct parent, move it to the namespace.2565if (LVScope *Scope = Element->getParentScope())2566Scope->removeElement(Element);2567Namespace->addElement(Element);2568}25692570return Error::success();2571}25722573// LF_UDT_SRC_LINE (TPI)/(IPI)2574Error LVLogicalVisitor::visitKnownRecord(CVType &Record,2575UdtSourceLineRecord &SourceLine,2576TypeIndex TI, LVElement *Element) {2577// All args are references into the TPI/IPI stream.2578LLVM_DEBUG({2579printTypeIndex("\nTI", TI, StreamIPI);2580printTypeIndex("UDT", SourceLine.getUDT(), StreamIPI);2581printTypeIndex("SourceFile", SourceLine.getSourceFile(), StreamIPI);2582W.printNumber("LineNumber", SourceLine.getLineNumber());2583});2584return Error::success();2585}25862587// LF_UDT_MOD_SRC_LINE (TPI)/(IPI)2588Error LVLogicalVisitor::visitKnownRecord(CVType &Record,2589UdtModSourceLineRecord &ModSourceLine,2590TypeIndex TI, LVElement *Element) {2591// All args are references into the TPI/IPI stream.2592LLVM_DEBUG({2593printTypeBegin(Record, TI, Element, StreamIPI);2594printTypeIndex("\nTI", TI, StreamIPI);2595printTypeIndex("UDT", ModSourceLine.getUDT(), StreamIPI);2596printTypeIndex("SourceFile", ModSourceLine.getSourceFile(), StreamIPI);2597W.printNumber("LineNumber", ModSourceLine.getLineNumber());2598W.printNumber("Module", ModSourceLine.getModule());2599printTypeEnd(Record);2600});2601return Error::success();2602}26032604// LF_PRECOMP (TPI)2605Error LVLogicalVisitor::visitKnownRecord(CVType &Record, PrecompRecord &Precomp,2606TypeIndex TI, LVElement *Element) {2607LLVM_DEBUG({2608printTypeBegin(Record, TI, Element, StreamTPI);2609W.printHex("StartIndex", Precomp.getStartTypeIndex());2610W.printHex("Count", Precomp.getTypesCount());2611W.printHex("Signature", Precomp.getSignature());2612W.printString("PrecompFile", Precomp.getPrecompFilePath());2613printTypeEnd(Record);2614});2615return Error::success();2616}26172618// LF_ENDPRECOMP (TPI)2619Error LVLogicalVisitor::visitKnownRecord(CVType &Record,2620EndPrecompRecord &EndPrecomp,2621TypeIndex TI, LVElement *Element) {2622LLVM_DEBUG({2623printTypeBegin(Record, TI, Element, StreamTPI);2624W.printHex("Signature", EndPrecomp.getSignature());2625printTypeEnd(Record);2626});2627return Error::success();2628}26292630Error LVLogicalVisitor::visitUnknownMember(CVMemberRecord &Record,2631TypeIndex TI) {2632LLVM_DEBUG({ W.printHex("UnknownMember", unsigned(Record.Kind)); });2633return Error::success();2634}26352636// LF_BCLASS, LF_BINTERFACE2637Error LVLogicalVisitor::visitKnownMember(CVMemberRecord &Record,2638BaseClassRecord &Base, TypeIndex TI,2639LVElement *Element) {2640LLVM_DEBUG({2641printMemberBegin(Record, TI, Element, StreamTPI);2642printTypeIndex("BaseType", Base.getBaseType(), StreamTPI);2643W.printHex("BaseOffset", Base.getBaseOffset());2644printMemberEnd(Record);2645});26462647createElement(Record.Kind);2648if (LVSymbol *Symbol = CurrentSymbol) {2649LVElement *BaseClass = getElement(StreamTPI, Base.getBaseType());2650Symbol->setName(BaseClass->getName());2651Symbol->setType(BaseClass);2652Symbol->setAccessibilityCode(Base.getAccess());2653static_cast<LVScope *>(Element)->addElement(Symbol);2654}26552656return Error::success();2657}26582659// LF_MEMBER2660Error LVLogicalVisitor::visitKnownMember(CVMemberRecord &Record,2661DataMemberRecord &Field, TypeIndex TI,2662LVElement *Element) {2663LLVM_DEBUG({2664printMemberBegin(Record, TI, Element, StreamTPI);2665printTypeIndex("Type", Field.getType(), StreamTPI);2666W.printHex("FieldOffset", Field.getFieldOffset());2667W.printString("Name", Field.getName());2668printMemberEnd(Record);2669});26702671// Create the data member.2672createDataMember(Record, static_cast<LVScope *>(Element), Field.getName(),2673Field.getType(), Field.getAccess());2674return Error::success();2675}26762677// LF_ENUMERATE2678Error LVLogicalVisitor::visitKnownMember(CVMemberRecord &Record,2679EnumeratorRecord &Enum, TypeIndex TI,2680LVElement *Element) {2681LLVM_DEBUG({2682printMemberBegin(Record, TI, Element, StreamTPI);2683W.printNumber("EnumValue", Enum.getValue());2684W.printString("Name", Enum.getName());2685printMemberEnd(Record);2686});26872688createElement(Record.Kind);2689if (LVType *Type = CurrentType) {2690Type->setName(Enum.getName());2691SmallString<16> Value;2692Enum.getValue().toString(Value, 16, true, true);2693Type->setValue(Value);2694static_cast<LVScope *>(Element)->addElement(CurrentType);2695}26962697return Error::success();2698}26992700// LF_INDEX2701Error LVLogicalVisitor::visitKnownMember(CVMemberRecord &Record,2702ListContinuationRecord &Cont,2703TypeIndex TI, LVElement *Element) {2704LLVM_DEBUG({2705printMemberBegin(Record, TI, Element, StreamTPI);2706printTypeIndex("ContinuationIndex", Cont.getContinuationIndex(), StreamTPI);2707printMemberEnd(Record);2708});2709return Error::success();2710}27112712// LF_NESTTYPE2713Error LVLogicalVisitor::visitKnownMember(CVMemberRecord &Record,2714NestedTypeRecord &Nested, TypeIndex TI,2715LVElement *Element) {2716LLVM_DEBUG({2717printMemberBegin(Record, TI, Element, StreamTPI);2718printTypeIndex("Type", Nested.getNestedType(), StreamTPI);2719W.printString("Name", Nested.getName());2720printMemberEnd(Record);2721});27222723if (LVElement *Typedef = createElement(SymbolKind::S_UDT)) {2724Typedef->setName(Nested.getName());2725LVElement *NestedType = getElement(StreamTPI, Nested.getNestedType());2726Typedef->setType(NestedType);2727LVScope *Scope = static_cast<LVScope *>(Element);2728Scope->addElement(Typedef);27292730if (NestedType && NestedType->getIsNested()) {2731// 'Element' is an aggregate type that may contains this nested type2732// definition. Used their scoped names, to decide on their relationship.2733StringRef RecordName = getRecordName(types(), TI);27342735StringRef NestedTypeName = NestedType->getName();2736if (NestedTypeName.size() && RecordName.size()) {2737StringRef OuterComponent;2738std::tie(OuterComponent, std::ignore) =2739getInnerComponent(NestedTypeName);2740// We have an already created nested type. Add it to the current scope2741// and update all its children if any.2742if (OuterComponent.size() && OuterComponent == RecordName) {2743if (!NestedType->getIsScopedAlready()) {2744Scope->addElement(NestedType);2745NestedType->setIsScopedAlready();2746NestedType->updateLevel(Scope);2747}2748Typedef->resetIncludeInPrint();2749}2750}2751}2752}27532754return Error::success();2755}27562757// LF_ONEMETHOD2758Error LVLogicalVisitor::visitKnownMember(CVMemberRecord &Record,2759OneMethodRecord &Method, TypeIndex TI,2760LVElement *Element) {2761LLVM_DEBUG({2762printMemberBegin(Record, TI, Element, StreamTPI);2763printTypeIndex("Type", Method.getType(), StreamTPI);2764// If virtual, then read the vftable offset.2765if (Method.isIntroducingVirtual())2766W.printHex("VFTableOffset", Method.getVFTableOffset());2767W.printString("Name", Method.getName());2768printMemberEnd(Record);2769});27702771// All the LF_ONEMETHOD objects share the same type description.2772// We have to create a scope object for each one and get the required2773// information from the LF_MFUNCTION object.2774ProcessArgumentList = true;2775if (LVElement *MemberFunction = createElement(TypeLeafKind::LF_ONEMETHOD)) {2776MemberFunction->setIsFinalized();2777static_cast<LVScope *>(Element)->addElement(MemberFunction);27782779MemberFunction->setName(Method.getName());2780MemberFunction->setAccessibilityCode(Method.getAccess());27812782MethodKind Kind = Method.getMethodKind();2783if (Kind == MethodKind::Static)2784MemberFunction->setIsStatic();2785MemberFunction->setVirtualityCode(Kind);27862787MethodOptions Flags = Method.Attrs.getFlags();2788if (MethodOptions::CompilerGenerated ==2789(Flags & MethodOptions::CompilerGenerated))2790MemberFunction->setIsArtificial();27912792LazyRandomTypeCollection &Types = types();2793CVType CVMethodType = Types.getType(Method.getType());2794if (Error Err =2795finishVisitation(CVMethodType, Method.getType(), MemberFunction))2796return Err;2797}2798ProcessArgumentList = false;27992800return Error::success();2801}28022803// LF_METHOD2804Error LVLogicalVisitor::visitKnownMember(CVMemberRecord &Record,2805OverloadedMethodRecord &Method,2806TypeIndex TI, LVElement *Element) {2807LLVM_DEBUG({2808printMemberBegin(Record, TI, Element, StreamTPI);2809W.printHex("MethodCount", Method.getNumOverloads());2810printTypeIndex("MethodListIndex", Method.getMethodList(), StreamTPI);2811W.printString("Name", Method.getName());2812printMemberEnd(Record);2813});28142815// Record the overloaded method name, which will be used during the2816// traversal of the method list.2817LazyRandomTypeCollection &Types = types();2818OverloadedMethodName = Method.getName();2819CVType CVMethods = Types.getType(Method.getMethodList());2820if (Error Err = finishVisitation(CVMethods, Method.getMethodList(), Element))2821return Err;28222823return Error::success();2824}28252826// LF_STMEMBER2827Error LVLogicalVisitor::visitKnownMember(CVMemberRecord &Record,2828StaticDataMemberRecord &Field,2829TypeIndex TI, LVElement *Element) {2830LLVM_DEBUG({2831printMemberBegin(Record, TI, Element, StreamTPI);2832printTypeIndex("Type", Field.getType(), StreamTPI);2833W.printString("Name", Field.getName());2834printMemberEnd(Record);2835});28362837// Create the data member.2838createDataMember(Record, static_cast<LVScope *>(Element), Field.getName(),2839Field.getType(), Field.getAccess());2840return Error::success();2841}28422843// LF_VFUNCTAB2844Error LVLogicalVisitor::visitKnownMember(CVMemberRecord &Record,2845VFPtrRecord &VFTable, TypeIndex TI,2846LVElement *Element) {2847LLVM_DEBUG({2848printMemberBegin(Record, TI, Element, StreamTPI);2849printTypeIndex("Type", VFTable.getType(), StreamTPI);2850printMemberEnd(Record);2851});2852return Error::success();2853}28542855// LF_VBCLASS, LF_IVBCLASS2856Error LVLogicalVisitor::visitKnownMember(CVMemberRecord &Record,2857VirtualBaseClassRecord &Base,2858TypeIndex TI, LVElement *Element) {2859LLVM_DEBUG({2860printMemberBegin(Record, TI, Element, StreamTPI);2861printTypeIndex("BaseType", Base.getBaseType(), StreamTPI);2862printTypeIndex("VBPtrType", Base.getVBPtrType(), StreamTPI);2863W.printHex("VBPtrOffset", Base.getVBPtrOffset());2864W.printHex("VBTableIndex", Base.getVTableIndex());2865printMemberEnd(Record);2866});28672868createElement(Record.Kind);2869if (LVSymbol *Symbol = CurrentSymbol) {2870LVElement *BaseClass = getElement(StreamTPI, Base.getBaseType());2871Symbol->setName(BaseClass->getName());2872Symbol->setType(BaseClass);2873Symbol->setAccessibilityCode(Base.getAccess());2874Symbol->setVirtualityCode(MethodKind::Virtual);2875static_cast<LVScope *>(Element)->addElement(Symbol);2876}28772878return Error::success();2879}28802881Error LVLogicalVisitor::visitMemberRecord(CVMemberRecord &Record,2882TypeVisitorCallbacks &Callbacks,2883TypeIndex TI, LVElement *Element) {2884if (Error Err = Callbacks.visitMemberBegin(Record))2885return Err;28862887switch (Record.Kind) {2888default:2889if (Error Err = Callbacks.visitUnknownMember(Record))2890return Err;2891break;2892#define MEMBER_RECORD(EnumName, EnumVal, Name) \2893case EnumName: { \2894if (Error Err = \2895visitKnownMember<Name##Record>(Record, Callbacks, TI, Element)) \2896return Err; \2897break; \2898}2899#define MEMBER_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName) \2900MEMBER_RECORD(EnumVal, EnumVal, AliasName)2901#define TYPE_RECORD(EnumName, EnumVal, Name)2902#define TYPE_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName)2903#include "llvm/DebugInfo/CodeView/CodeViewTypes.def"2904}29052906if (Error Err = Callbacks.visitMemberEnd(Record))2907return Err;29082909return Error::success();2910}29112912Error LVLogicalVisitor::finishVisitation(CVType &Record, TypeIndex TI,2913LVElement *Element) {2914switch (Record.kind()) {2915default:2916if (Error Err = visitUnknownType(Record, TI))2917return Err;2918break;2919#define TYPE_RECORD(EnumName, EnumVal, Name) \2920case EnumName: { \2921if (Error Err = visitKnownRecord<Name##Record>(Record, TI, Element)) \2922return Err; \2923break; \2924}2925#define TYPE_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName) \2926TYPE_RECORD(EnumVal, EnumVal, AliasName)2927#define MEMBER_RECORD(EnumName, EnumVal, Name)2928#define MEMBER_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName)2929#include "llvm/DebugInfo/CodeView/CodeViewTypes.def"2930}29312932return Error::success();2933}29342935// Customized version of 'FieldListVisitHelper'.2936Error LVLogicalVisitor::visitFieldListMemberStream(2937TypeIndex TI, LVElement *Element, ArrayRef<uint8_t> FieldList) {2938BinaryByteStream Stream(FieldList, llvm::endianness::little);2939BinaryStreamReader Reader(Stream);2940FieldListDeserializer Deserializer(Reader);2941TypeVisitorCallbackPipeline Pipeline;2942Pipeline.addCallbackToPipeline(Deserializer);29432944TypeLeafKind Leaf;2945while (!Reader.empty()) {2946if (Error Err = Reader.readEnum(Leaf))2947return Err;29482949CVMemberRecord Record;2950Record.Kind = Leaf;2951if (Error Err = visitMemberRecord(Record, Pipeline, TI, Element))2952return Err;2953}29542955return Error::success();2956}29572958void LVLogicalVisitor::addElement(LVScope *Scope, bool IsCompileUnit) {2959// The CodeView specifications does not treat S_COMPILE2 and S_COMPILE32960// as symbols that open a scope. The CodeView reader, treat them in a2961// similar way as DWARF. As there is no a symbole S_END to close the2962// compile unit, we need to check for the next compile unit.2963if (IsCompileUnit) {2964if (!ScopeStack.empty())2965popScope();2966InCompileUnitScope = true;2967}29682969pushScope(Scope);2970ReaderParent->addElement(Scope);2971}29722973void LVLogicalVisitor::addElement(LVSymbol *Symbol) {2974ReaderScope->addElement(Symbol);2975}29762977void LVLogicalVisitor::addElement(LVType *Type) {2978ReaderScope->addElement(Type);2979}29802981LVElement *LVLogicalVisitor::createElement(TypeLeafKind Kind) {2982CurrentScope = nullptr;2983CurrentSymbol = nullptr;2984CurrentType = nullptr;29852986if (Kind < TypeIndex::FirstNonSimpleIndex) {2987CurrentType = Reader->createType();2988CurrentType->setIsBase();2989CurrentType->setTag(dwarf::DW_TAG_base_type);2990if (options().getAttributeBase())2991CurrentType->setIncludeInPrint();2992return CurrentType;2993}29942995switch (Kind) {2996// Types.2997case TypeLeafKind::LF_ENUMERATE:2998CurrentType = Reader->createTypeEnumerator();2999CurrentType->setTag(dwarf::DW_TAG_enumerator);3000return CurrentType;3001case TypeLeafKind::LF_MODIFIER:3002CurrentType = Reader->createType();3003CurrentType->setIsModifier();3004return CurrentType;3005case TypeLeafKind::LF_POINTER:3006CurrentType = Reader->createType();3007CurrentType->setIsPointer();3008CurrentType->setName("*");3009CurrentType->setTag(dwarf::DW_TAG_pointer_type);3010return CurrentType;30113012// Symbols.3013case TypeLeafKind::LF_BCLASS:3014case TypeLeafKind::LF_IVBCLASS:3015case TypeLeafKind::LF_VBCLASS:3016CurrentSymbol = Reader->createSymbol();3017CurrentSymbol->setTag(dwarf::DW_TAG_inheritance);3018CurrentSymbol->setIsInheritance();3019return CurrentSymbol;3020case TypeLeafKind::LF_MEMBER:3021case TypeLeafKind::LF_STMEMBER:3022CurrentSymbol = Reader->createSymbol();3023CurrentSymbol->setIsMember();3024CurrentSymbol->setTag(dwarf::DW_TAG_member);3025return CurrentSymbol;30263027// Scopes.3028case TypeLeafKind::LF_ARRAY:3029CurrentScope = Reader->createScopeArray();3030CurrentScope->setTag(dwarf::DW_TAG_array_type);3031return CurrentScope;3032case TypeLeafKind::LF_CLASS:3033CurrentScope = Reader->createScopeAggregate();3034CurrentScope->setTag(dwarf::DW_TAG_class_type);3035CurrentScope->setIsClass();3036return CurrentScope;3037case TypeLeafKind::LF_ENUM:3038CurrentScope = Reader->createScopeEnumeration();3039CurrentScope->setTag(dwarf::DW_TAG_enumeration_type);3040return CurrentScope;3041case TypeLeafKind::LF_METHOD:3042case TypeLeafKind::LF_ONEMETHOD:3043case TypeLeafKind::LF_PROCEDURE:3044CurrentScope = Reader->createScopeFunction();3045CurrentScope->setIsSubprogram();3046CurrentScope->setTag(dwarf::DW_TAG_subprogram);3047return CurrentScope;3048case TypeLeafKind::LF_STRUCTURE:3049CurrentScope = Reader->createScopeAggregate();3050CurrentScope->setIsStructure();3051CurrentScope->setTag(dwarf::DW_TAG_structure_type);3052return CurrentScope;3053case TypeLeafKind::LF_UNION:3054CurrentScope = Reader->createScopeAggregate();3055CurrentScope->setIsUnion();3056CurrentScope->setTag(dwarf::DW_TAG_union_type);3057return CurrentScope;3058default:3059// If '--internal=tag' and '--print=warning' are specified in the command3060// line, we record and print each seen 'TypeLeafKind'.3061break;3062}3063return nullptr;3064}30653066LVElement *LVLogicalVisitor::createElement(SymbolKind Kind) {3067CurrentScope = nullptr;3068CurrentSymbol = nullptr;3069CurrentType = nullptr;3070switch (Kind) {3071// Types.3072case SymbolKind::S_UDT:3073CurrentType = Reader->createTypeDefinition();3074CurrentType->setTag(dwarf::DW_TAG_typedef);3075return CurrentType;30763077// Symbols.3078case SymbolKind::S_CONSTANT:3079CurrentSymbol = Reader->createSymbol();3080CurrentSymbol->setIsConstant();3081CurrentSymbol->setTag(dwarf::DW_TAG_constant);3082return CurrentSymbol;30833084case SymbolKind::S_BPREL32:3085case SymbolKind::S_REGREL32:3086case SymbolKind::S_GDATA32:3087case SymbolKind::S_LDATA32:3088case SymbolKind::S_LOCAL:3089// During the symbol traversal more information is available to3090// determine if the symbol is a parameter or a variable. At this3091// stage mark it as variable.3092CurrentSymbol = Reader->createSymbol();3093CurrentSymbol->setIsVariable();3094CurrentSymbol->setTag(dwarf::DW_TAG_variable);3095return CurrentSymbol;30963097// Scopes.3098case SymbolKind::S_BLOCK32:3099CurrentScope = Reader->createScope();3100CurrentScope->setIsLexicalBlock();3101CurrentScope->setTag(dwarf::DW_TAG_lexical_block);3102return CurrentScope;3103case SymbolKind::S_COMPILE2:3104case SymbolKind::S_COMPILE3:3105CurrentScope = Reader->createScopeCompileUnit();3106CurrentScope->setTag(dwarf::DW_TAG_compile_unit);3107Reader->setCompileUnit(static_cast<LVScopeCompileUnit *>(CurrentScope));3108return CurrentScope;3109case SymbolKind::S_INLINESITE:3110case SymbolKind::S_INLINESITE2:3111CurrentScope = Reader->createScopeFunctionInlined();3112CurrentScope->setIsInlinedFunction();3113CurrentScope->setTag(dwarf::DW_TAG_inlined_subroutine);3114return CurrentScope;3115case SymbolKind::S_LPROC32:3116case SymbolKind::S_GPROC32:3117case SymbolKind::S_LPROC32_ID:3118case SymbolKind::S_GPROC32_ID:3119case SymbolKind::S_SEPCODE:3120case SymbolKind::S_THUNK32:3121CurrentScope = Reader->createScopeFunction();3122CurrentScope->setIsSubprogram();3123CurrentScope->setTag(dwarf::DW_TAG_subprogram);3124return CurrentScope;3125default:3126// If '--internal=tag' and '--print=warning' are specified in the command3127// line, we record and print each seen 'SymbolKind'.3128break;3129}3130return nullptr;3131}31323133LVElement *LVLogicalVisitor::createElement(TypeIndex TI, TypeLeafKind Kind) {3134LVElement *Element = Shared->TypeRecords.find(StreamTPI, TI);3135if (!Element) {3136// We are dealing with a base type or pointer to a base type, which are3137// not included explicitly in the CodeView format.3138if (Kind < TypeIndex::FirstNonSimpleIndex) {3139Element = createElement(Kind);3140Element->setIsFinalized();3141Shared->TypeRecords.add(StreamTPI, (TypeIndex)Kind, Kind, Element);3142Element->setOffset(Kind);3143return Element;3144}3145// We are dealing with a pointer to a base type.3146if (TI.getIndex() < TypeIndex::FirstNonSimpleIndex) {3147Element = createElement(Kind);3148Shared->TypeRecords.add(StreamTPI, TI, Kind, Element);3149Element->setOffset(TI.getIndex());3150Element->setOffsetFromTypeIndex();3151return Element;3152}31533154W.printString("** Not implemented. **");3155printTypeIndex("TypeIndex", TI, StreamTPI);3156W.printString("TypeLeafKind", formatTypeLeafKind(Kind));3157return nullptr;3158}31593160Element->setOffset(TI.getIndex());3161Element->setOffsetFromTypeIndex();3162return Element;3163}31643165void LVLogicalVisitor::createDataMember(CVMemberRecord &Record, LVScope *Parent,3166StringRef Name, TypeIndex TI,3167MemberAccess Access) {3168LLVM_DEBUG({3169printTypeIndex("TypeIndex", TI, StreamTPI);3170W.printString("TypeName", Name);3171});31723173createElement(Record.Kind);3174if (LVSymbol *Symbol = CurrentSymbol) {3175Symbol->setName(Name);3176if (TI.isNoneType() || TI.isSimple())3177Symbol->setType(getElement(StreamTPI, TI));3178else {3179LazyRandomTypeCollection &Types = types();3180CVType CVMemberType = Types.getType(TI);3181if (CVMemberType.kind() == LF_BITFIELD) {3182if (Error Err = finishVisitation(CVMemberType, TI, Symbol)) {3183consumeError(std::move(Err));3184return;3185}3186} else3187Symbol->setType(getElement(StreamTPI, TI));3188}3189Symbol->setAccessibilityCode(Access);3190Parent->addElement(Symbol);3191}3192}31933194LVSymbol *LVLogicalVisitor::createParameter(LVElement *Element, StringRef Name,3195LVScope *Parent) {3196LVSymbol *Parameter = Reader->createSymbol();3197Parent->addElement(Parameter);3198Parameter->setIsParameter();3199Parameter->setTag(dwarf::DW_TAG_formal_parameter);3200Parameter->setName(Name);3201Parameter->setType(Element);3202return Parameter;3203}32043205LVSymbol *LVLogicalVisitor::createParameter(TypeIndex TI, StringRef Name,3206LVScope *Parent) {3207return createParameter(getElement(StreamTPI, TI), Name, Parent);3208}32093210LVType *LVLogicalVisitor::createBaseType(TypeIndex TI, StringRef TypeName) {3211TypeLeafKind SimpleKind = (TypeLeafKind)TI.getSimpleKind();3212TypeIndex TIR = (TypeIndex)SimpleKind;3213LLVM_DEBUG({3214printTypeIndex("TypeIndex", TIR, StreamTPI);3215W.printString("TypeName", TypeName);3216});32173218if (LVElement *Element = Shared->TypeRecords.find(StreamTPI, TIR))3219return static_cast<LVType *>(Element);32203221if (createElement(TIR, SimpleKind)) {3222CurrentType->setName(TypeName);3223Reader->getCompileUnit()->addElement(CurrentType);3224}3225return CurrentType;3226}32273228LVType *LVLogicalVisitor::createPointerType(TypeIndex TI, StringRef TypeName) {3229LLVM_DEBUG({3230printTypeIndex("TypeIndex", TI, StreamTPI);3231W.printString("TypeName", TypeName);3232});32333234if (LVElement *Element = Shared->TypeRecords.find(StreamTPI, TI))3235return static_cast<LVType *>(Element);32363237LVType *Pointee = createBaseType(TI, TypeName.drop_back(1));3238if (createElement(TI, TypeLeafKind::LF_POINTER)) {3239CurrentType->setIsFinalized();3240CurrentType->setType(Pointee);3241Reader->getCompileUnit()->addElement(CurrentType);3242}3243return CurrentType;3244}32453246void LVLogicalVisitor::createParents(StringRef ScopedName, LVElement *Element) {3247// For the given test case:3248//3249// struct S { enum E { ... }; };3250// S::E V;3251//3252// 0 | S_LOCAL `V`3253// type=0x1004 (S::E), flags = none3254// 0x1004 | LF_ENUM `S::E`3255// options: has unique name | is nested3256// 0x1009 | LF_STRUCTURE `S`3257// options: contains nested class3258//3259// When the local 'V' is processed, its type 'E' is created. But There is3260// no direct reference to its parent 'S'. We use the scoped name for 'E',3261// to create its parents.32623263// The input scoped name must have at least parent and nested names.3264// Drop the last element name, as it corresponds to the nested type.3265LVStringRefs Components = getAllLexicalComponents(ScopedName);3266if (Components.size() < 2)3267return;3268Components.pop_back();32693270LVStringRefs::size_type FirstNamespace;3271LVStringRefs::size_type FirstAggregate;3272std::tie(FirstNamespace, FirstAggregate) =3273Shared->NamespaceDeduction.find(Components);32743275LLVM_DEBUG({3276W.printString("First Namespace", Components[FirstNamespace]);3277W.printString("First NonNamespace", Components[FirstAggregate]);3278});32793280// Create any referenced namespaces.3281if (FirstNamespace < FirstAggregate) {3282Shared->NamespaceDeduction.get(3283LVStringRefs(Components.begin() + FirstNamespace,3284Components.begin() + FirstAggregate));3285}32863287// Traverse the enclosing scopes (aggregates) and create them. In the3288// case of nested empty aggregates, MSVC does not emit a full record3289// description. It emits only the reference record.3290LVScope *Aggregate = nullptr;3291TypeIndex TIAggregate;3292std::string AggregateName = getScopedName(3293LVStringRefs(Components.begin(), Components.begin() + FirstAggregate));32943295// This traversal is executed at least once.3296for (LVStringRefs::size_type Index = FirstAggregate;3297Index < Components.size(); ++Index) {3298AggregateName = getScopedName(LVStringRefs(Components.begin() + Index,3299Components.begin() + Index + 1),3300AggregateName);3301TIAggregate = Shared->ForwardReferences.remap(3302Shared->TypeRecords.find(StreamTPI, AggregateName));3303Aggregate =3304TIAggregate.isNoneType()3305? nullptr3306: static_cast<LVScope *>(getElement(StreamTPI, TIAggregate));3307}33083309// Workaround for cases where LF_NESTTYPE is missing for nested templates.3310// If we manage to get parent information from the scoped name, we can add3311// the nested type without relying on the LF_NESTTYPE.3312if (Aggregate && !Element->getIsScopedAlready()) {3313Aggregate->addElement(Element);3314Element->setIsScopedAlready();3315}3316}33173318LVElement *LVLogicalVisitor::getElement(uint32_t StreamIdx, TypeIndex TI,3319LVScope *Parent) {3320LLVM_DEBUG({ printTypeIndex("TypeIndex", TI, StreamTPI); });3321TI = Shared->ForwardReferences.remap(TI);3322LLVM_DEBUG({ printTypeIndex("TypeIndex Remap", TI, StreamTPI); });33233324LVElement *Element = Shared->TypeRecords.find(StreamIdx, TI);3325if (!Element) {3326if (TI.isNoneType() || TI.isSimple()) {3327StringRef TypeName = TypeIndex::simpleTypeName(TI);3328// If the name ends with "*", create 2 logical types: a pointer and a3329// pointee type. TypeIndex is composed of a SympleTypeMode byte followed3330// by a SimpleTypeKind byte. The logical pointer will be identified by3331// the full TypeIndex value and the pointee by the SimpleTypeKind.3332return (TypeName.back() == '*') ? createPointerType(TI, TypeName)3333: createBaseType(TI, TypeName);3334}33353336LLVM_DEBUG({ W.printHex("TypeIndex not implemented: ", TI.getIndex()); });3337return nullptr;3338}33393340// The element has been finalized.3341if (Element->getIsFinalized())3342return Element;33433344// Add the element in case of a given parent.3345if (Parent)3346Parent->addElement(Element);33473348// Check for a composite type.3349LazyRandomTypeCollection &Types = types();3350CVType CVRecord = Types.getType(TI);3351if (Error Err = finishVisitation(CVRecord, TI, Element)) {3352consumeError(std::move(Err));3353return nullptr;3354}3355Element->setIsFinalized();3356return Element;3357}33583359void LVLogicalVisitor::processLines() {3360// Traverse the collected LF_UDT_SRC_LINE records and add the source line3361// information to the logical elements.3362for (const TypeIndex &Entry : Shared->LineRecords) {3363CVType CVRecord = ids().getType(Entry);3364UdtSourceLineRecord Line;3365if (Error Err = TypeDeserializer::deserializeAs(3366const_cast<CVType &>(CVRecord), Line))3367consumeError(std::move(Err));3368else {3369LLVM_DEBUG({3370printTypeIndex("UDT", Line.getUDT(), StreamIPI);3371printTypeIndex("SourceFile", Line.getSourceFile(), StreamIPI);3372W.printNumber("LineNumber", Line.getLineNumber());3373});33743375// The TypeIndex returned by 'getUDT()' must point to an already3376// created logical element. If no logical element is found, it means3377// the LF_UDT_SRC_LINE is associated with a system TypeIndex.3378if (LVElement *Element = Shared->TypeRecords.find(3379StreamTPI, Line.getUDT(), /*Create=*/false)) {3380Element->setLineNumber(Line.getLineNumber());3381Element->setFilenameIndex(3382Shared->StringRecords.findIndex(Line.getSourceFile()));3383}3384}3385}3386}33873388void LVLogicalVisitor::processNamespaces() {3389// Create namespaces.3390Shared->NamespaceDeduction.init();3391}33923393void LVLogicalVisitor::processFiles() { Shared->StringRecords.addFilenames(); }33943395void LVLogicalVisitor::printRecords(raw_ostream &OS) const {3396if (!options().getInternalTag())3397return;33983399unsigned Count = 0;3400auto PrintItem = [&](StringRef Name) {3401auto NewLine = [&]() {3402if (++Count == 4) {3403Count = 0;3404OS << "\n";3405}3406};3407OS << format("%20s", Name.str().c_str());3408NewLine();3409};34103411OS << "\nTypes:\n";3412for (const TypeLeafKind &Kind : Shared->TypeKinds)3413PrintItem(formatTypeLeafKind(Kind));3414Shared->TypeKinds.clear();34153416Count = 0;3417OS << "\nSymbols:\n";3418for (const SymbolKind &Kind : Shared->SymbolKinds)3419PrintItem(LVCodeViewReader::getSymbolKindName(Kind));3420Shared->SymbolKinds.clear();34213422OS << "\n";3423}34243425Error LVLogicalVisitor::inlineSiteAnnotation(LVScope *AbstractFunction,3426LVScope *InlinedFunction,3427InlineSiteSym &InlineSite) {3428// Get the parent scope to update the address ranges of the nested3429// scope representing the inlined function.3430LVAddress ParentLowPC = 0;3431LVScope *Parent = InlinedFunction->getParentScope();3432if (const LVLocations *Locations = Parent->getRanges()) {3433if (!Locations->empty())3434ParentLowPC = (*Locations->begin())->getLowerAddress();3435}34363437// For the given inlinesite, get the initial line number and its3438// source filename. Update the logical scope representing it.3439uint32_t LineNumber = 0;3440StringRef Filename;3441LVInlineeInfo::iterator Iter = InlineeInfo.find(InlineSite.Inlinee);3442if (Iter != InlineeInfo.end()) {3443LineNumber = Iter->second.first;3444Filename = Iter->second.second;3445AbstractFunction->setLineNumber(LineNumber);3446// TODO: This part needs additional work in order to set properly the3447// correct filename in order to detect changes between filenames.3448// AbstractFunction->setFilename(Filename);3449}34503451LLVM_DEBUG({3452dbgs() << "inlineSiteAnnotation\n"3453<< "Abstract: " << AbstractFunction->getName() << "\n"3454<< "Inlined: " << InlinedFunction->getName() << "\n"3455<< "Parent: " << Parent->getName() << "\n"3456<< "Low PC: " << hexValue(ParentLowPC) << "\n";3457});34583459// Get the source lines if requested by command line option.3460if (!options().getPrintLines())3461return Error::success();34623463// Limitation: Currently we don't track changes in the FileOffset. The3464// side effects are the caller that it is unable to differentiate the3465// source filename for the inlined code.3466uint64_t CodeOffset = ParentLowPC;3467int32_t LineOffset = LineNumber;3468uint32_t FileOffset = 0;34693470auto UpdateClose = [&]() { LLVM_DEBUG({ dbgs() << ("\n"); }); };3471auto UpdateCodeOffset = [&](uint32_t Delta) {3472CodeOffset += Delta;3473LLVM_DEBUG({3474dbgs() << formatv(" code 0x{0} (+0x{1})", utohexstr(CodeOffset),3475utohexstr(Delta));3476});3477};3478auto UpdateLineOffset = [&](int32_t Delta) {3479LineOffset += Delta;3480LLVM_DEBUG({3481char Sign = Delta > 0 ? '+' : '-';3482dbgs() << formatv(" line {0} ({1}{2})", LineOffset, Sign,3483std::abs(Delta));3484});3485};3486auto UpdateFileOffset = [&](int32_t Offset) {3487FileOffset = Offset;3488LLVM_DEBUG({ dbgs() << formatv(" file {0}", FileOffset); });3489};34903491LVLines InlineeLines;3492auto CreateLine = [&]() {3493// Create the logical line record.3494LVLineDebug *Line = Reader->createLineDebug();3495Line->setAddress(CodeOffset);3496Line->setLineNumber(LineOffset);3497// TODO: This part needs additional work in order to set properly the3498// correct filename in order to detect changes between filenames.3499// Line->setFilename(Filename);3500InlineeLines.push_back(Line);3501};35023503bool SeenLowAddress = false;3504bool SeenHighAddress = false;3505uint64_t LowPC = 0;3506uint64_t HighPC = 0;35073508for (auto &Annot : InlineSite.annotations()) {3509LLVM_DEBUG({3510dbgs() << formatv(" {0}",3511fmt_align(toHex(Annot.Bytes), AlignStyle::Left, 9));3512});35133514// Use the opcode to interpret the integer values.3515switch (Annot.OpCode) {3516case BinaryAnnotationsOpCode::ChangeCodeOffset:3517case BinaryAnnotationsOpCode::CodeOffset:3518case BinaryAnnotationsOpCode::ChangeCodeLength:3519UpdateCodeOffset(Annot.U1);3520UpdateClose();3521if (Annot.OpCode == BinaryAnnotationsOpCode::ChangeCodeOffset) {3522CreateLine();3523LowPC = CodeOffset;3524SeenLowAddress = true;3525break;3526}3527if (Annot.OpCode == BinaryAnnotationsOpCode::ChangeCodeLength) {3528HighPC = CodeOffset - 1;3529SeenHighAddress = true;3530}3531break;3532case BinaryAnnotationsOpCode::ChangeCodeLengthAndCodeOffset:3533UpdateCodeOffset(Annot.U2);3534UpdateClose();3535break;3536case BinaryAnnotationsOpCode::ChangeLineOffset:3537case BinaryAnnotationsOpCode::ChangeCodeOffsetAndLineOffset:3538UpdateCodeOffset(Annot.U1);3539UpdateLineOffset(Annot.S1);3540UpdateClose();3541if (Annot.OpCode ==3542BinaryAnnotationsOpCode::ChangeCodeOffsetAndLineOffset)3543CreateLine();3544break;3545case BinaryAnnotationsOpCode::ChangeFile:3546UpdateFileOffset(Annot.U1);3547UpdateClose();3548break;3549default:3550break;3551}3552if (SeenLowAddress && SeenHighAddress) {3553SeenLowAddress = false;3554SeenHighAddress = false;3555InlinedFunction->addObject(LowPC, HighPC);3556}3557}35583559Reader->addInlineeLines(InlinedFunction, InlineeLines);3560UpdateClose();35613562return Error::success();3563}356435653566