3561 lines · cpp
1//===-- LVCodeViewVisitor.cpp ---------------------------------------------===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8//9// This implements the LVCodeViewVisitor class.10//11//===----------------------------------------------------------------------===//12 13#include "llvm/DebugInfo/LogicalView/Readers/LVCodeViewVisitor.h"14#include "llvm/BinaryFormat/Magic.h"15#include "llvm/DebugInfo/CodeView/EnumTables.h"16#include "llvm/DebugInfo/CodeView/LazyRandomTypeCollection.h"17#include "llvm/DebugInfo/CodeView/SymbolRecordHelpers.h"18#include "llvm/DebugInfo/CodeView/TypeRecordHelpers.h"19#include "llvm/DebugInfo/CodeView/TypeVisitorCallbackPipeline.h"20#include "llvm/DebugInfo/LogicalView/Core/LVScope.h"21#include "llvm/DebugInfo/LogicalView/Core/LVSymbol.h"22#include "llvm/DebugInfo/LogicalView/Core/LVType.h"23#include "llvm/DebugInfo/LogicalView/Readers/LVCodeViewReader.h"24#include "llvm/DebugInfo/PDB/Native/InputFile.h"25#include "llvm/DebugInfo/PDB/Native/PDBFile.h"26#include "llvm/DebugInfo/PDB/Native/PDBStringTable.h"27#include "llvm/DebugInfo/PDB/Native/TpiStream.h"28#include "llvm/Demangle/Demangle.h"29#include "llvm/Object/COFF.h"30#include "llvm/Support/Error.h"31#include "llvm/Support/FormatAdapters.h"32#include "llvm/Support/FormatVariadic.h"33 34using namespace llvm;35using namespace llvm::codeview;36using namespace llvm::object;37using namespace llvm::pdb;38using namespace llvm::logicalview;39 40#define DEBUG_TYPE "CodeViewUtilities"41 42namespace llvm {43namespace logicalview {44 45static TypeIndex getTrueType(TypeIndex &TI) {46 // Dealing with a MSVC generated PDB, we encountered a type index with the47 // value of: 0x0280xxxx where xxxx=0000.48 //49 // There is some documentation about type indices:50 // https://llvm.org/docs/PDB/TpiStream.html51 //52 // A type index is a 32-bit integer that uniquely identifies a type inside53 // of an object file’s .debug$T section or a PDB file’s TPI or IPI stream.54 // The value of the type index for the first type record from the TPI stream55 // is given by the TypeIndexBegin member of the TPI Stream Header although56 // in practice this value is always equal to 0x1000 (4096).57 //58 // Any type index with a high bit set is considered to come from the IPI59 // stream, although this appears to be more of a hack, and LLVM does not60 // generate type indices of this nature. They can, however, be observed in61 // Microsoft PDBs occasionally, so one should be prepared to handle them.62 // Note that having the high bit set is not a necessary condition to63 // determine whether a type index comes from the IPI stream, it is only64 // sufficient.65 LLVM_DEBUG(66 { dbgs() << "Index before: " << HexNumber(TI.getIndex()) << "\n"; });67 TI.setIndex(TI.getIndex() & 0x0000ffff);68 LLVM_DEBUG(69 { dbgs() << "Index after: " << HexNumber(TI.getIndex()) << "\n"; });70 return TI;71}72 73static const EnumEntry<TypeLeafKind> LeafTypeNames[] = {74#define CV_TYPE(enum, val) {#enum, enum},75#include "llvm/DebugInfo/CodeView/CodeViewTypes.def"76};77 78// Return the type name pointed by the type index. It uses the kind to query79// the associated name for the record type.80static StringRef getRecordName(LazyRandomTypeCollection &Types, TypeIndex TI) {81 if (TI.isSimple())82 return {};83 84 StringRef RecordName;85 CVType CVReference = Types.getType(TI);86 auto GetName = [&](auto Record) {87 if (Error Err = TypeDeserializer::deserializeAs(88 const_cast<CVType &>(CVReference), Record))89 consumeError(std::move(Err));90 else91 RecordName = Record.getName();92 };93 94 TypeRecordKind RK = static_cast<TypeRecordKind>(CVReference.kind());95 if (RK == TypeRecordKind::Class || RK == TypeRecordKind::Struct)96 GetName(ClassRecord(RK));97 else if (RK == TypeRecordKind::Union)98 GetName(UnionRecord(RK));99 else if (RK == TypeRecordKind::Enum)100 GetName(EnumRecord(RK));101 102 return RecordName;103}104 105} // namespace logicalview106} // namespace llvm107 108#undef DEBUG_TYPE109#define DEBUG_TYPE "CodeViewDataVisitor"110 111namespace llvm {112namespace logicalview {113 114// Keeps the type indexes with line information.115using LVLineRecords = std::vector<TypeIndex>;116 117namespace {118 119class LVTypeRecords {120 LVShared *Shared = nullptr;121 122 // Logical elements associated to their CodeView Type Index.123 using RecordEntry = std::pair<TypeLeafKind, LVElement *>;124 using RecordTable = std::map<TypeIndex, RecordEntry>;125 RecordTable RecordFromTypes;126 RecordTable RecordFromIds;127 128 using NameTable = std::map<StringRef, TypeIndex>;129 NameTable NameFromTypes;130 NameTable NameFromIds;131 132public:133 LVTypeRecords(LVShared *Shared) : Shared(Shared) {}134 135 void add(uint32_t StreamIdx, TypeIndex TI, TypeLeafKind Kind,136 LVElement *Element = nullptr);137 void add(uint32_t StreamIdx, TypeIndex TI, StringRef Name);138 LVElement *find(uint32_t StreamIdx, TypeIndex TI, bool Create = true);139 TypeIndex find(uint32_t StreamIdx, StringRef Name);140};141 142class LVForwardReferences {143 // Forward reference and its definitions (Name as key).144 using ForwardEntry = std::pair<TypeIndex, TypeIndex>;145 using ForwardTypeNames = std::map<StringRef, ForwardEntry>;146 ForwardTypeNames ForwardTypesNames;147 148 // Forward reference and its definition (TypeIndex as key).149 using ForwardType = std::map<TypeIndex, TypeIndex>;150 ForwardType ForwardTypes;151 152 // Forward types and its references.153 void add(TypeIndex TIForward, TypeIndex TIReference) {154 ForwardTypes.emplace(TIForward, TIReference);155 }156 157 void add(StringRef Name, TypeIndex TIForward) {158 auto [It, Inserted] =159 ForwardTypesNames.try_emplace(Name, TIForward, TypeIndex::None());160 if (!Inserted) {161 // Update a recorded definition with its reference.162 It->second.first = TIForward;163 add(TIForward, It->second.second);164 }165 }166 167 // Update a previously recorded forward reference with its definition.168 void update(StringRef Name, TypeIndex TIReference) {169 auto [It, Inserted] =170 ForwardTypesNames.try_emplace(Name, TypeIndex::None(), TIReference);171 if (!Inserted) {172 // Update the recorded forward reference with its definition.173 It->second.second = TIReference;174 add(It->second.first, TIReference);175 }176 }177 178public:179 LVForwardReferences() = default;180 181 void record(bool IsForwardRef, StringRef Name, TypeIndex TI) {182 // We are expecting for the forward references to be first. But that183 // is not always the case. A name must be recorded regardless of the184 // order in which the forward reference appears.185 (IsForwardRef) ? add(Name, TI) : update(Name, TI);186 }187 188 TypeIndex find(TypeIndex TIForward) {189 auto It = ForwardTypes.find(TIForward);190 return It != ForwardTypes.end() ? It->second : TypeIndex::None();191 }192 193 TypeIndex find(StringRef Name) {194 auto It = ForwardTypesNames.find(Name);195 return It != ForwardTypesNames.end() ? It->second.second196 : TypeIndex::None();197 }198 199 // If the given TI corresponds to a reference, return the reference.200 // Otherwise return the given TI.201 TypeIndex remap(TypeIndex TI) {202 TypeIndex Forward = find(TI);203 return Forward.isNoneType() ? TI : Forward;204 }205};206 207// Namespace deduction.208class LVNamespaceDeduction {209 LVShared *Shared = nullptr;210 211 using Names = std::map<StringRef, LVScope *>;212 Names NamespaceNames;213 214 using LookupSet = std::set<StringRef>;215 LookupSet DeducedScopes;216 LookupSet UnresolvedScopes;217 LookupSet IdentifiedNamespaces;218 219 void add(StringRef Name, LVScope *Namespace) {220 if (NamespaceNames.find(Name) == NamespaceNames.end())221 NamespaceNames.emplace(Name, Namespace);222 }223 224public:225 LVNamespaceDeduction(LVShared *Shared) : Shared(Shared) {}226 227 void init();228 void add(StringRef String);229 LVScope *get(LVStringRefs Components);230 LVScope *get(StringRef Name, bool CheckScope = true);231 232 // Find the logical namespace for the 'Name' component.233 LVScope *find(StringRef Name) {234 auto It = NamespaceNames.find(Name);235 LVScope *Namespace = It != NamespaceNames.end() ? It->second : nullptr;236 return Namespace;237 }238 239 // For the given lexical components, return a tuple with the first entry240 // being the outermost namespace and the second entry being the first241 // non-namespace.242 LVLexicalIndex find(LVStringRefs Components) {243 if (Components.empty())244 return {};245 246 LVStringRefs::size_type FirstNamespace = 0;247 LVStringRefs::size_type FirstNonNamespace;248 for (LVStringRefs::size_type Index = 0; Index < Components.size();249 ++Index) {250 FirstNonNamespace = Index;251 LookupSet::iterator Iter = IdentifiedNamespaces.find(Components[Index]);252 if (Iter == IdentifiedNamespaces.end())253 // The component is not a namespace name.254 break;255 }256 return std::make_tuple(FirstNamespace, FirstNonNamespace);257 }258};259 260// Strings.261class LVStringRecords {262 using StringEntry = std::tuple<uint32_t, std::string, LVScopeCompileUnit *>;263 using StringIds = std::map<TypeIndex, StringEntry>;264 StringIds Strings;265 266public:267 LVStringRecords() = default;268 269 void add(TypeIndex TI, StringRef String) {270 static uint32_t Index = 0;271 auto [It, Inserted] = Strings.try_emplace(TI);272 if (Inserted)273 It->second = std::make_tuple(++Index, std::string(String), nullptr);274 }275 276 StringRef find(TypeIndex TI) {277 StringIds::iterator Iter = Strings.find(TI);278 return Iter != Strings.end() ? std::get<1>(Iter->second) : StringRef{};279 }280 281 uint32_t findIndex(TypeIndex TI) {282 StringIds::iterator Iter = Strings.find(TI);283 return Iter != Strings.end() ? std::get<0>(Iter->second) : 0;284 }285 286 // Move strings representing the filenames to the compile unit.287 void addFilenames();288 void addFilenames(LVScopeCompileUnit *Scope);289};290} // namespace291 292using LVTypeKinds = std::set<TypeLeafKind>;293using LVSymbolKinds = std::set<SymbolKind>;294 295// The following data keeps forward information, type records, names for296// namespace deduction, strings records, line records.297// It is shared by the type visitor, symbol visitor and logical visitor and298// it is independent from the CodeViewReader.299struct LVShared {300 LVCodeViewReader *Reader;301 LVLogicalVisitor *Visitor;302 LVForwardReferences ForwardReferences;303 LVLineRecords LineRecords;304 LVNamespaceDeduction NamespaceDeduction;305 LVStringRecords StringRecords;306 LVTypeRecords TypeRecords;307 308 // In order to determine which types and/or symbols records should be handled309 // by the reader, we record record kinds seen by the type and symbol visitors.310 // At the end of the scopes creation, the '--internal=tag' option will allow311 // to print the unique record ids collected.312 LVTypeKinds TypeKinds;313 LVSymbolKinds SymbolKinds;314 315 LVShared(LVCodeViewReader *Reader, LVLogicalVisitor *Visitor)316 : Reader(Reader), Visitor(Visitor), NamespaceDeduction(this),317 TypeRecords(this) {}318 ~LVShared() = default;319};320} // namespace logicalview321} // namespace llvm322 323void LVTypeRecords::add(uint32_t StreamIdx, TypeIndex TI, TypeLeafKind Kind,324 LVElement *Element) {325 RecordTable &Target =326 (StreamIdx == StreamTPI) ? RecordFromTypes : RecordFromIds;327 Target.emplace(std::piecewise_construct, std::forward_as_tuple(TI),328 std::forward_as_tuple(Kind, Element));329}330 331void LVTypeRecords::add(uint32_t StreamIdx, TypeIndex TI, StringRef Name) {332 NameTable &Target = (StreamIdx == StreamTPI) ? NameFromTypes : NameFromIds;333 Target.emplace(Name, TI);334}335 336LVElement *LVTypeRecords::find(uint32_t StreamIdx, TypeIndex TI, bool Create) {337 RecordTable &Target =338 (StreamIdx == StreamTPI) ? RecordFromTypes : RecordFromIds;339 340 LVElement *Element = nullptr;341 RecordTable::iterator Iter = Target.find(TI);342 if (Iter != Target.end()) {343 Element = Iter->second.second;344 if (Element || !Create)345 return Element;346 347 // Create the logical element if not found.348 Element = Shared->Visitor->createElement(Iter->second.first);349 if (Element) {350 Element->setOffset(TI.getIndex());351 Element->setOffsetFromTypeIndex();352 Target[TI].second = Element;353 }354 }355 return Element;356}357 358TypeIndex LVTypeRecords::find(uint32_t StreamIdx, StringRef Name) {359 NameTable &Target = (StreamIdx == StreamTPI) ? NameFromTypes : NameFromIds;360 NameTable::iterator Iter = Target.find(Name);361 return Iter != Target.end() ? Iter->second : TypeIndex::None();362}363 364void LVStringRecords::addFilenames() {365 for (StringIds::const_reference Entry : Strings) {366 StringRef Name = std::get<1>(Entry.second);367 LVScopeCompileUnit *Scope = std::get<2>(Entry.second);368 Scope->addFilename(transformPath(Name));369 }370 Strings.clear();371}372 373void LVStringRecords::addFilenames(LVScopeCompileUnit *Scope) {374 for (StringIds::reference Entry : Strings)375 if (!std::get<2>(Entry.second))376 std::get<2>(Entry.second) = Scope;377}378 379void LVNamespaceDeduction::add(StringRef String) {380 StringRef InnerComponent;381 StringRef OuterComponent;382 std::tie(OuterComponent, InnerComponent) = getInnerComponent(String);383 DeducedScopes.insert(InnerComponent);384 if (OuterComponent.size())385 UnresolvedScopes.insert(OuterComponent);386}387 388void LVNamespaceDeduction::init() {389 // We have 2 sets of names:390 // - deduced scopes (class, structure, union and enum) and391 // - unresolved scopes, that can represent namespaces or any deduced.392 // Before creating the namespaces, we have to traverse the unresolved393 // and remove any references to already deduced scopes.394 LVStringRefs Components;395 for (const StringRef &Unresolved : UnresolvedScopes) {396 Components = getAllLexicalComponents(Unresolved);397 for (const StringRef &Component : Components) {398 LookupSet::iterator Iter = DeducedScopes.find(Component);399 if (Iter == DeducedScopes.end())400 IdentifiedNamespaces.insert(Component);401 }402 }403 404 LLVM_DEBUG({405 auto Print = [&](LookupSet &Container, const char *Title) {406 auto Header = [&]() {407 dbgs() << formatv("\n{0}\n", fmt_repeat('=', 72));408 dbgs() << formatv("{0}\n", Title);409 dbgs() << formatv("{0}\n", fmt_repeat('=', 72));410 };411 Header();412 for (const StringRef &Item : Container)413 dbgs() << formatv("'{0}'\n", Item.str().c_str());414 };415 416 Print(DeducedScopes, "Deducted Scopes");417 Print(UnresolvedScopes, "Unresolved Scopes");418 Print(IdentifiedNamespaces, "Namespaces");419 });420}421 422LVScope *LVNamespaceDeduction::get(LVStringRefs Components) {423 LLVM_DEBUG({424 for (const StringRef &Component : Components)425 dbgs() << formatv("'{0}'\n", Component.str().c_str());426 });427 428 if (Components.empty())429 return nullptr;430 431 // Update the namespaces relationship.432 LVScope *Namespace = nullptr;433 LVScope *Parent = Shared->Reader->getCompileUnit();434 for (const StringRef &Component : Components) {435 // Check if we have seen the namespace.436 Namespace = find(Component);437 if (!Namespace) {438 // We have identified namespaces that are generated by MSVC. Mark them439 // as 'system' so they will be excluded from the logical view.440 Namespace = Shared->Reader->createScopeNamespace();441 Namespace->setTag(dwarf::DW_TAG_namespace);442 Namespace->setName(Component);443 Parent->addElement(Namespace);444 getReader().isSystemEntry(Namespace);445 add(Component, Namespace);446 }447 Parent = Namespace;448 }449 return Parent;450}451 452LVScope *LVNamespaceDeduction::get(StringRef ScopedName, bool CheckScope) {453 LVStringRefs Components = getAllLexicalComponents(ScopedName);454 if (CheckScope)455 llvm::erase_if(Components, [&](StringRef Component) {456 LookupSet::iterator Iter = IdentifiedNamespaces.find(Component);457 return Iter == IdentifiedNamespaces.end();458 });459 460 LLVM_DEBUG(461 { dbgs() << formatv("ScopedName: '{0}'\n", ScopedName.str().c_str()); });462 463 return get(Components);464}465 466#undef DEBUG_TYPE467#define DEBUG_TYPE "CodeViewTypeVisitor"468 469//===----------------------------------------------------------------------===//470// TypeRecord traversal.471//===----------------------------------------------------------------------===//472void LVTypeVisitor::printTypeIndex(StringRef FieldName, TypeIndex TI,473 uint32_t StreamIdx) const {474 codeview::printTypeIndex(W, FieldName, TI,475 StreamIdx == StreamTPI ? Types : Ids);476}477 478Error LVTypeVisitor::visitTypeBegin(CVType &Record) {479 return visitTypeBegin(Record, TypeIndex::fromArrayIndex(Types.size()));480}481 482Error LVTypeVisitor::visitTypeBegin(CVType &Record, TypeIndex TI) {483 LLVM_DEBUG({484 W.getOStream() << formatTypeLeafKind(Record.kind());485 W.getOStream() << " (" << HexNumber(TI.getIndex()) << ")\n";486 });487 488 if (options().getInternalTag())489 Shared->TypeKinds.insert(Record.kind());490 491 // The collected type records, will be use to create the logical elements492 // during the symbols traversal when a type is referenced.493 CurrentTypeIndex = TI;494 Shared->TypeRecords.add(StreamIdx, TI, Record.kind());495 return Error::success();496}497 498Error LVTypeVisitor::visitUnknownType(CVType &Record) {499 LLVM_DEBUG({ W.printNumber("Length", uint32_t(Record.content().size())); });500 return Error::success();501}502 503Error LVTypeVisitor::visitMemberBegin(CVMemberRecord &Record) {504 LLVM_DEBUG({505 W.startLine() << formatTypeLeafKind(Record.Kind);506 W.getOStream() << " {\n";507 W.indent();508 });509 return Error::success();510}511 512Error LVTypeVisitor::visitMemberEnd(CVMemberRecord &Record) {513 LLVM_DEBUG({514 W.unindent();515 W.startLine() << "}\n";516 });517 return Error::success();518}519 520Error LVTypeVisitor::visitUnknownMember(CVMemberRecord &Record) {521 LLVM_DEBUG({ W.printHex("UnknownMember", unsigned(Record.Kind)); });522 return Error::success();523}524 525// LF_BUILDINFO (TPI)/(IPI)526Error LVTypeVisitor::visitKnownRecord(CVType &Record, BuildInfoRecord &Args) {527 // All the args are references into the TPI/IPI stream.528 LLVM_DEBUG({529 W.printNumber("NumArgs", static_cast<uint32_t>(Args.getArgs().size()));530 ListScope Arguments(W, "Arguments");531 for (TypeIndex Arg : Args.getArgs())532 printTypeIndex("ArgType", Arg, StreamIPI);533 });534 535 // Only add the strings that hold information about filenames. They will be536 // used to complete the line/file information for the logical elements.537 // There are other strings holding information about namespaces.538 TypeIndex TI;539 StringRef String;540 541 // Absolute CWD path542 TI = Args.getArgs()[BuildInfoRecord::BuildInfoArg::CurrentDirectory];543 String = Ids.getTypeName(TI);544 if (!String.empty())545 Shared->StringRecords.add(TI, String);546 547 // Get the compile unit name.548 TI = Args.getArgs()[BuildInfoRecord::BuildInfoArg::SourceFile];549 String = Ids.getTypeName(TI);550 if (!String.empty())551 Shared->StringRecords.add(TI, String);552 LogicalVisitor->setCompileUnitName(std::string(String));553 554 return Error::success();555}556 557// LF_CLASS, LF_STRUCTURE, LF_INTERFACE (TPI)558Error LVTypeVisitor::visitKnownRecord(CVType &Record, ClassRecord &Class) {559 LLVM_DEBUG({560 printTypeIndex("TypeIndex", CurrentTypeIndex, StreamTPI);561 printTypeIndex("FieldListType", Class.getFieldList(), StreamTPI);562 W.printString("Name", Class.getName());563 });564 565 // Collect class name for scope deduction.566 Shared->NamespaceDeduction.add(Class.getName());567 Shared->ForwardReferences.record(Class.isForwardRef(), Class.getName(),568 CurrentTypeIndex);569 570 // Collect class name for contained scopes deduction.571 Shared->TypeRecords.add(StreamIdx, CurrentTypeIndex, Class.getName());572 return Error::success();573}574 575// LF_ENUM (TPI)576Error LVTypeVisitor::visitKnownRecord(CVType &Record, EnumRecord &Enum) {577 LLVM_DEBUG({578 printTypeIndex("TypeIndex", CurrentTypeIndex, StreamTPI);579 printTypeIndex("FieldListType", Enum.getFieldList(), StreamTPI);580 W.printString("Name", Enum.getName());581 });582 583 // Collect enum name for scope deduction.584 Shared->NamespaceDeduction.add(Enum.getName());585 return Error::success();586}587 588// LF_FUNC_ID (TPI)/(IPI)589Error LVTypeVisitor::visitKnownRecord(CVType &Record, FuncIdRecord &Func) {590 LLVM_DEBUG({591 printTypeIndex("TypeIndex", CurrentTypeIndex, StreamTPI);592 printTypeIndex("Type", Func.getFunctionType(), StreamTPI);593 printTypeIndex("Parent", Func.getParentScope(), StreamTPI);594 W.printString("Name", Func.getName());595 });596 597 // Collect function name for scope deduction.598 Shared->NamespaceDeduction.add(Func.getName());599 return Error::success();600}601 602// LF_PROCEDURE (TPI)603Error LVTypeVisitor::visitKnownRecord(CVType &Record, ProcedureRecord &Proc) {604 LLVM_DEBUG({605 printTypeIndex("TypeIndex", CurrentTypeIndex, StreamTPI);606 printTypeIndex("ReturnType", Proc.getReturnType(), StreamTPI);607 W.printNumber("NumParameters", Proc.getParameterCount());608 printTypeIndex("ArgListType", Proc.getArgumentList(), StreamTPI);609 });610 611 // Collect procedure information as they can be referenced by typedefs.612 Shared->TypeRecords.add(StreamTPI, CurrentTypeIndex, {});613 return Error::success();614}615 616// LF_STRING_ID (TPI)/(IPI)617Error LVTypeVisitor::visitKnownRecord(CVType &Record, StringIdRecord &String) {618 // No additional references are needed.619 LLVM_DEBUG({620 printTypeIndex("Id", String.getId(), StreamIPI);621 W.printString("StringData", String.getString());622 });623 return Error::success();624}625 626// LF_UDT_SRC_LINE (TPI)/(IPI)627Error LVTypeVisitor::visitKnownRecord(CVType &Record,628 UdtSourceLineRecord &Line) {629 // UDT and SourceFile are references into the TPI/IPI stream.630 LLVM_DEBUG({631 printTypeIndex("UDT", Line.getUDT(), StreamIPI);632 printTypeIndex("SourceFile", Line.getSourceFile(), StreamIPI);633 W.printNumber("LineNumber", Line.getLineNumber());634 });635 636 Shared->LineRecords.push_back(CurrentTypeIndex);637 return Error::success();638}639 640// LF_UNION (TPI)641Error LVTypeVisitor::visitKnownRecord(CVType &Record, UnionRecord &Union) {642 LLVM_DEBUG({643 W.printNumber("MemberCount", Union.getMemberCount());644 printTypeIndex("FieldList", Union.getFieldList(), StreamTPI);645 W.printNumber("SizeOf", Union.getSize());646 W.printString("Name", Union.getName());647 if (Union.hasUniqueName())648 W.printString("UniqueName", Union.getUniqueName());649 });650 651 // Collect union name for scope deduction.652 Shared->NamespaceDeduction.add(Union.getName());653 Shared->ForwardReferences.record(Union.isForwardRef(), Union.getName(),654 CurrentTypeIndex);655 656 // Collect class name for contained scopes deduction.657 Shared->TypeRecords.add(StreamIdx, CurrentTypeIndex, Union.getName());658 return Error::success();659}660 661#undef DEBUG_TYPE662#define DEBUG_TYPE "CodeViewSymbolVisitor"663 664//===----------------------------------------------------------------------===//665// SymbolRecord traversal.666//===----------------------------------------------------------------------===//667void LVSymbolVisitorDelegate::printRelocatedField(StringRef Label,668 uint32_t RelocOffset,669 uint32_t Offset,670 StringRef *RelocSym) {671 Reader->printRelocatedField(Label, CoffSection, RelocOffset, Offset,672 RelocSym);673}674 675void LVSymbolVisitorDelegate::getLinkageName(uint32_t RelocOffset,676 uint32_t Offset,677 StringRef *RelocSym) {678 Reader->getLinkageName(CoffSection, RelocOffset, Offset, RelocSym);679}680 681StringRef682LVSymbolVisitorDelegate::getFileNameForFileOffset(uint32_t FileOffset) {683 Expected<StringRef> Name = Reader->getFileNameForFileOffset(FileOffset);684 if (!Name) {685 consumeError(Name.takeError());686 return {};687 }688 return *Name;689}690 691DebugStringTableSubsectionRef LVSymbolVisitorDelegate::getStringTable() {692 return Reader->CVStringTable;693}694 695void LVSymbolVisitor::printLocalVariableAddrRange(696 const LocalVariableAddrRange &Range, uint32_t RelocationOffset) {697 DictScope S(W, "LocalVariableAddrRange");698 if (ObjDelegate)699 ObjDelegate->printRelocatedField("OffsetStart", RelocationOffset,700 Range.OffsetStart);701 W.printHex("ISectStart", Range.ISectStart);702 W.printHex("Range", Range.Range);703}704 705void LVSymbolVisitor::printLocalVariableAddrGap(706 ArrayRef<LocalVariableAddrGap> Gaps) {707 for (const LocalVariableAddrGap &Gap : Gaps) {708 ListScope S(W, "LocalVariableAddrGap");709 W.printHex("GapStartOffset", Gap.GapStartOffset);710 W.printHex("Range", Gap.Range);711 }712}713 714void LVSymbolVisitor::printTypeIndex(StringRef FieldName, TypeIndex TI) const {715 codeview::printTypeIndex(W, FieldName, TI, Types);716}717 718Error LVSymbolVisitor::visitSymbolBegin(CVSymbol &Record) {719 return visitSymbolBegin(Record, 0);720}721 722Error LVSymbolVisitor::visitSymbolBegin(CVSymbol &Record, uint32_t Offset) {723 SymbolKind Kind = Record.kind();724 LLVM_DEBUG({725 W.printNumber("Offset", Offset);726 W.printEnum("Begin Kind", unsigned(Kind), getSymbolTypeNames());727 });728 729 if (options().getInternalTag())730 Shared->SymbolKinds.insert(Kind);731 732 LogicalVisitor->CurrentElement = LogicalVisitor->createElement(Kind);733 if (!LogicalVisitor->CurrentElement) {734 LLVM_DEBUG({735 // We have an unsupported Symbol or Type Record.736 // W.printEnum("Kind ignored", unsigned(Kind), getSymbolTypeNames());737 });738 return Error::success();739 }740 741 // Offset carried by the traversal routines when dealing with streams.742 CurrentOffset = Offset;743 IsCompileUnit = false;744 if (!LogicalVisitor->CurrentElement->getOffsetFromTypeIndex())745 LogicalVisitor->CurrentElement->setOffset(Offset);746 if (symbolOpensScope(Kind) || (IsCompileUnit = symbolIsCompileUnit(Kind))) {747 assert(LogicalVisitor->CurrentScope && "Invalid scope!");748 LogicalVisitor->addElement(LogicalVisitor->CurrentScope, IsCompileUnit);749 } else {750 if (LogicalVisitor->CurrentSymbol)751 LogicalVisitor->addElement(LogicalVisitor->CurrentSymbol);752 if (LogicalVisitor->CurrentType)753 LogicalVisitor->addElement(LogicalVisitor->CurrentType);754 }755 756 return Error::success();757}758 759Error LVSymbolVisitor::visitSymbolEnd(CVSymbol &Record) {760 SymbolKind Kind = Record.kind();761 LLVM_DEBUG(762 { W.printEnum("End Kind", unsigned(Kind), getSymbolTypeNames()); });763 764 if (symbolEndsScope(Kind)) {765 LogicalVisitor->popScope();766 }767 768 return Error::success();769}770 771Error LVSymbolVisitor::visitUnknownSymbol(CVSymbol &Record) {772 LLVM_DEBUG({ W.printNumber("Length", Record.length()); });773 return Error::success();774}775 776// S_BLOCK32777Error LVSymbolVisitor::visitKnownRecord(CVSymbol &Record, BlockSym &Block) {778 LLVM_DEBUG({779 W.printHex("CodeSize", Block.CodeSize);780 W.printHex("Segment", Block.Segment);781 W.printString("BlockName", Block.Name);782 });783 784 if (LVScope *Scope = LogicalVisitor->CurrentScope) {785 StringRef LinkageName;786 if (ObjDelegate)787 ObjDelegate->getLinkageName(Block.getRelocationOffset(), Block.CodeOffset,788 &LinkageName);789 Scope->setLinkageName(LinkageName);790 791 if (options().getGeneralCollectRanges()) {792 // Record converted segment::offset addressing for this scope.793 LVAddress Addendum = Reader->getSymbolTableAddress(LinkageName);794 LVAddress LowPC =795 Reader->linearAddress(Block.Segment, Block.CodeOffset, Addendum);796 LVAddress HighPC = LowPC + Block.CodeSize - 1;797 Scope->addObject(LowPC, HighPC);798 }799 }800 801 return Error::success();802}803 804// S_BPREL32805Error LVSymbolVisitor::visitKnownRecord(CVSymbol &Record,806 BPRelativeSym &Local) {807 LLVM_DEBUG({808 printTypeIndex("Type", Local.Type);809 W.printNumber("Offset", Local.Offset);810 W.printString("VarName", Local.Name);811 });812 813 if (LVSymbol *Symbol = LogicalVisitor->CurrentSymbol) {814 Symbol->setName(Local.Name);815 // From the MS_Symbol_Type.pdf documentation (S_BPREL32):816 // This symbol specifies symbols that are allocated on the stack for a817 // procedure. For C and C++, these include the actual function parameters818 // and the local non-static variables of functions.819 // However, the offset for 'this' comes as a negative value.820 821 // Symbol was created as 'variable'; determine its real kind.822 Symbol->resetIsVariable();823 824 if (Local.Name == "this") {825 Symbol->setIsParameter();826 Symbol->setIsArtificial();827 } else {828 // Determine symbol kind.829 bool(Local.Offset > 0) ? Symbol->setIsParameter()830 : Symbol->setIsVariable();831 }832 833 // Update correct debug information tag.834 if (Symbol->getIsParameter())835 Symbol->setTag(dwarf::DW_TAG_formal_parameter);836 837 LVElement *Element = LogicalVisitor->getElement(StreamTPI, Local.Type);838 if (Element && Element->getIsScoped()) {839 // We have a local type. Find its parent function.840 LVScope *Parent = Symbol->getFunctionParent();841 // The element representing the type has been already finalized. If842 // the type is an aggregate type, its members have been already added.843 // As the type is local, its level will be changed.844 845 // FIXME: Currently the algorithm used to scope lambda functions is846 // incorrect. Before we allocate the type at this scope, check if is847 // already allocated in other scope.848 if (!Element->getParentScope()) {849 Parent->addElement(Element);850 Element->updateLevel(Parent);851 }852 }853 Symbol->setType(Element);854 }855 856 return Error::success();857}858 859// S_REGREL32860Error LVSymbolVisitor::visitKnownRecord(CVSymbol &Record,861 RegRelativeSym &Local) {862 LLVM_DEBUG({863 printTypeIndex("Type", Local.Type);864 W.printNumber("Offset", Local.Offset);865 W.printString("VarName", Local.Name);866 });867 868 if (LVSymbol *Symbol = LogicalVisitor->CurrentSymbol) {869 Symbol->setName(Local.Name);870 871 // Symbol was created as 'variable'; determine its real kind.872 Symbol->resetIsVariable();873 874 // Check for the 'this' symbol.875 if (Local.Name == "this") {876 Symbol->setIsArtificial();877 Symbol->setIsParameter();878 } else {879 // Determine symbol kind.880 determineSymbolKind(Symbol, Local.Register);881 }882 883 // Update correct debug information tag.884 if (Symbol->getIsParameter())885 Symbol->setTag(dwarf::DW_TAG_formal_parameter);886 887 LVElement *Element = LogicalVisitor->getElement(StreamTPI, Local.Type);888 if (Element && Element->getIsScoped()) {889 // We have a local type. Find its parent function.890 LVScope *Parent = Symbol->getFunctionParent();891 // The element representing the type has been already finalized. If892 // the type is an aggregate type, its members have been already added.893 // As the type is local, its level will be changed.894 895 // FIXME: Currently the algorithm used to scope lambda functions is896 // incorrect. Before we allocate the type at this scope, check if is897 // already allocated in other scope.898 if (!Element->getParentScope()) {899 Parent->addElement(Element);900 Element->updateLevel(Parent);901 }902 }903 Symbol->setType(Element);904 }905 906 return Error::success();907}908 909// S_BUILDINFO910Error LVSymbolVisitor::visitKnownRecord(CVSymbol &CVR,911 BuildInfoSym &BuildInfo) {912 LLVM_DEBUG({ printTypeIndex("BuildId", BuildInfo.BuildId); });913 914 CVType CVBuildType = Ids.getType(BuildInfo.BuildId);915 if (Error Err = LogicalVisitor->finishVisitation(916 CVBuildType, BuildInfo.BuildId, Reader->getCompileUnit()))917 return Err;918 919 return Error::success();920}921 922// S_COMPILE2923Error LVSymbolVisitor::visitKnownRecord(CVSymbol &Record,924 Compile2Sym &Compile2) {925 LLVM_DEBUG({926 W.printEnum("Language", uint8_t(Compile2.getLanguage()),927 getSourceLanguageNames());928 W.printFlags("Flags", uint32_t(Compile2.getFlags()),929 getCompileSym3FlagNames());930 W.printEnum("Machine", unsigned(Compile2.Machine), getCPUTypeNames());931 W.printString("VersionName", Compile2.Version);932 });933 934 // MSVC generates the following sequence for a CodeView module:935 // S_OBJNAME --> Set 'CurrentObjectName'.936 // S_COMPILE2 --> Set the compile unit name using 'CurrentObjectName'.937 // ...938 // S_BUILDINFO --> Extract the source name.939 //940 // Clang generates the following sequence for a CodeView module:941 // S_COMPILE2 --> Set the compile unit name to empty string.942 // ...943 // S_BUILDINFO --> Extract the source name.944 //945 // For both toolchains, update the compile unit name from S_BUILDINFO.946 if (LVScope *Scope = LogicalVisitor->CurrentScope) {947 // The name of the CU, was extracted from the 'BuildInfo' subsection.948 Reader->setCompileUnitCPUType(Compile2.Machine);949 Scope->setName(CurrentObjectName);950 if (options().getAttributeProducer())951 Scope->setProducer(Compile2.Version);952 if (options().getAttributeLanguage())953 Scope->setSourceLanguage(LVSourceLanguage{954 static_cast<llvm::codeview::SourceLanguage>(Compile2.getLanguage())});955 getReader().isSystemEntry(Scope, CurrentObjectName);956 957 // The line records in CodeView are recorded per Module ID. Update958 // the relationship between the current CU and the Module ID.959 Reader->addModule(Scope);960 961 // Updated the collected strings with their associated compile unit.962 Shared->StringRecords.addFilenames(Reader->getCompileUnit());963 }964 965 // Clear any previous ObjectName.966 CurrentObjectName = "";967 return Error::success();968}969 970// S_COMPILE3971Error LVSymbolVisitor::visitKnownRecord(CVSymbol &Record,972 Compile3Sym &Compile3) {973 LLVM_DEBUG({974 W.printEnum("Language", uint8_t(Compile3.getLanguage()),975 getSourceLanguageNames());976 W.printFlags("Flags", uint32_t(Compile3.getFlags()),977 getCompileSym3FlagNames());978 W.printEnum("Machine", unsigned(Compile3.Machine), getCPUTypeNames());979 W.printString("VersionName", Compile3.Version);980 });981 982 // MSVC generates the following sequence for a CodeView module:983 // S_OBJNAME --> Set 'CurrentObjectName'.984 // S_COMPILE3 --> Set the compile unit name using 'CurrentObjectName'.985 // ...986 // S_BUILDINFO --> Extract the source name.987 //988 // Clang generates the following sequence for a CodeView module:989 // S_COMPILE3 --> Set the compile unit name to empty string.990 // ...991 // S_BUILDINFO --> Extract the source name.992 //993 // For both toolchains, update the compile unit name from S_BUILDINFO.994 if (LVScope *Scope = LogicalVisitor->CurrentScope) {995 // The name of the CU, was extracted from the 'BuildInfo' subsection.996 Reader->setCompileUnitCPUType(Compile3.Machine);997 Scope->setName(CurrentObjectName);998 if (options().getAttributeProducer())999 Scope->setProducer(Compile3.Version);1000 if (options().getAttributeLanguage())1001 Scope->setSourceLanguage(LVSourceLanguage{1002 static_cast<llvm::codeview::SourceLanguage>(Compile3.getLanguage())});1003 getReader().isSystemEntry(Scope, CurrentObjectName);1004 1005 // The line records in CodeView are recorded per Module ID. Update1006 // the relationship between the current CU and the Module ID.1007 Reader->addModule(Scope);1008 1009 // Updated the collected strings with their associated compile unit.1010 Shared->StringRecords.addFilenames(Reader->getCompileUnit());1011 }1012 1013 // Clear any previous ObjectName.1014 CurrentObjectName = "";1015 return Error::success();1016}1017 1018// S_CONSTANT, S_MANCONSTANT1019Error LVSymbolVisitor::visitKnownRecord(CVSymbol &Record,1020 ConstantSym &Constant) {1021 LLVM_DEBUG({1022 printTypeIndex("Type", Constant.Type);1023 W.printNumber("Value", Constant.Value);1024 W.printString("Name", Constant.Name);1025 });1026 1027 if (LVSymbol *Symbol = LogicalVisitor->CurrentSymbol) {1028 Symbol->setName(Constant.Name);1029 Symbol->setType(LogicalVisitor->getElement(StreamTPI, Constant.Type));1030 Symbol->resetIncludeInPrint();1031 }1032 1033 return Error::success();1034}1035 1036// S_DEFRANGE_FRAMEPOINTER_REL_FULL_SCOPE1037Error LVSymbolVisitor::visitKnownRecord(1038 CVSymbol &Record,1039 DefRangeFramePointerRelFullScopeSym &DefRangeFramePointerRelFullScope) {1040 // DefRanges don't have types, just registers and code offsets.1041 LLVM_DEBUG({1042 if (LocalSymbol)1043 W.getOStream() << formatv("Symbol: {0}, ", LocalSymbol->getName());1044 1045 W.printNumber("Offset", DefRangeFramePointerRelFullScope.Offset);1046 });1047 1048 if (LVSymbol *Symbol = LocalSymbol) {1049 Symbol->setHasCodeViewLocation();1050 LocalSymbol = nullptr;1051 1052 // Add location debug location. Operands: [Offset, 0].1053 dwarf::Attribute Attr =1054 dwarf::Attribute(SymbolKind::S_DEFRANGE_FRAMEPOINTER_REL_FULL_SCOPE);1055 1056 uint64_t Operand1 = DefRangeFramePointerRelFullScope.Offset;1057 Symbol->addLocation(Attr, 0, 0, 0, 0);1058 Symbol->addLocationOperands(LVSmall(Attr), {Operand1});1059 }1060 1061 return Error::success();1062}1063 1064// S_DEFRANGE_FRAMEPOINTER_REL1065Error LVSymbolVisitor::visitKnownRecord(1066 CVSymbol &Record, DefRangeFramePointerRelSym &DefRangeFramePointerRel) {1067 // DefRanges don't have types, just registers and code offsets.1068 LLVM_DEBUG({1069 if (LocalSymbol)1070 W.getOStream() << formatv("Symbol: {0}, ", LocalSymbol->getName());1071 1072 W.printNumber("Offset", DefRangeFramePointerRel.Hdr.Offset);1073 printLocalVariableAddrRange(DefRangeFramePointerRel.Range,1074 DefRangeFramePointerRel.getRelocationOffset());1075 printLocalVariableAddrGap(DefRangeFramePointerRel.Gaps);1076 });1077 1078 // We are expecting the following sequence:1079 // 128 | S_LOCAL [size = 20] `ParamBar`1080 // ...1081 // 148 | S_DEFRANGE_FRAMEPOINTER_REL [size = 16]1082 if (LVSymbol *Symbol = LocalSymbol) {1083 Symbol->setHasCodeViewLocation();1084 LocalSymbol = nullptr;1085 1086 // Add location debug location. Operands: [Offset, 0].1087 dwarf::Attribute Attr =1088 dwarf::Attribute(SymbolKind::S_DEFRANGE_FRAMEPOINTER_REL);1089 uint64_t Operand1 = DefRangeFramePointerRel.Hdr.Offset;1090 1091 LocalVariableAddrRange Range = DefRangeFramePointerRel.Range;1092 LVAddress Address =1093 Reader->linearAddress(Range.ISectStart, Range.OffsetStart);1094 1095 Symbol->addLocation(Attr, Address, Address + Range.Range, 0, 0);1096 Symbol->addLocationOperands(LVSmall(Attr), {Operand1});1097 }1098 1099 return Error::success();1100}1101 1102// S_DEFRANGE_REGISTER_REL1103Error LVSymbolVisitor::visitKnownRecord(1104 CVSymbol &Record, DefRangeRegisterRelSym &DefRangeRegisterRel) {1105 // DefRanges don't have types, just registers and code offsets.1106 LLVM_DEBUG({1107 if (LocalSymbol)1108 W.getOStream() << formatv("Symbol: {0}, ", LocalSymbol->getName());1109 1110 W.printBoolean("HasSpilledUDTMember",1111 DefRangeRegisterRel.hasSpilledUDTMember());1112 W.printNumber("OffsetInParent", DefRangeRegisterRel.offsetInParent());1113 W.printNumber("BasePointerOffset",1114 DefRangeRegisterRel.Hdr.BasePointerOffset);1115 printLocalVariableAddrRange(DefRangeRegisterRel.Range,1116 DefRangeRegisterRel.getRelocationOffset());1117 printLocalVariableAddrGap(DefRangeRegisterRel.Gaps);1118 });1119 1120 if (LVSymbol *Symbol = LocalSymbol) {1121 Symbol->setHasCodeViewLocation();1122 LocalSymbol = nullptr;1123 1124 // Add location debug location. Operands: [Register, Offset].1125 dwarf::Attribute Attr =1126 dwarf::Attribute(SymbolKind::S_DEFRANGE_REGISTER_REL);1127 uint64_t Operand1 = DefRangeRegisterRel.Hdr.Register;1128 uint64_t Operand2 = DefRangeRegisterRel.Hdr.BasePointerOffset;1129 1130 LocalVariableAddrRange Range = DefRangeRegisterRel.Range;1131 LVAddress Address =1132 Reader->linearAddress(Range.ISectStart, Range.OffsetStart);1133 1134 Symbol->addLocation(Attr, Address, Address + Range.Range, 0, 0);1135 Symbol->addLocationOperands(LVSmall(Attr), {Operand1, Operand2});1136 }1137 1138 return Error::success();1139}1140 1141// S_DEFRANGE_REGISTER1142Error LVSymbolVisitor::visitKnownRecord(CVSymbol &Record,1143 DefRangeRegisterSym &DefRangeRegister) {1144 // DefRanges don't have types, just registers and code offsets.1145 LLVM_DEBUG({1146 if (LocalSymbol)1147 W.getOStream() << formatv("Symbol: {0}, ", LocalSymbol->getName());1148 1149 W.printEnum("Register", uint16_t(DefRangeRegister.Hdr.Register),1150 getRegisterNames(Reader->getCompileUnitCPUType()));1151 W.printNumber("MayHaveNoName", DefRangeRegister.Hdr.MayHaveNoName);1152 printLocalVariableAddrRange(DefRangeRegister.Range,1153 DefRangeRegister.getRelocationOffset());1154 printLocalVariableAddrGap(DefRangeRegister.Gaps);1155 });1156 1157 if (LVSymbol *Symbol = LocalSymbol) {1158 Symbol->setHasCodeViewLocation();1159 LocalSymbol = nullptr;1160 1161 // Add location debug location. Operands: [Register, 0].1162 dwarf::Attribute Attr = dwarf::Attribute(SymbolKind::S_DEFRANGE_REGISTER);1163 uint64_t Operand1 = DefRangeRegister.Hdr.Register;1164 1165 LocalVariableAddrRange Range = DefRangeRegister.Range;1166 LVAddress Address =1167 Reader->linearAddress(Range.ISectStart, Range.OffsetStart);1168 1169 Symbol->addLocation(Attr, Address, Address + Range.Range, 0, 0);1170 Symbol->addLocationOperands(LVSmall(Attr), {Operand1});1171 }1172 1173 return Error::success();1174}1175 1176// S_DEFRANGE_SUBFIELD_REGISTER1177Error LVSymbolVisitor::visitKnownRecord(1178 CVSymbol &Record, DefRangeSubfieldRegisterSym &DefRangeSubfieldRegister) {1179 // DefRanges don't have types, just registers and code offsets.1180 LLVM_DEBUG({1181 if (LocalSymbol)1182 W.getOStream() << formatv("Symbol: {0}, ", LocalSymbol->getName());1183 1184 W.printEnum("Register", uint16_t(DefRangeSubfieldRegister.Hdr.Register),1185 getRegisterNames(Reader->getCompileUnitCPUType()));1186 W.printNumber("MayHaveNoName", DefRangeSubfieldRegister.Hdr.MayHaveNoName);1187 W.printNumber("OffsetInParent",1188 DefRangeSubfieldRegister.Hdr.OffsetInParent);1189 printLocalVariableAddrRange(DefRangeSubfieldRegister.Range,1190 DefRangeSubfieldRegister.getRelocationOffset());1191 printLocalVariableAddrGap(DefRangeSubfieldRegister.Gaps);1192 });1193 1194 if (LVSymbol *Symbol = LocalSymbol) {1195 Symbol->setHasCodeViewLocation();1196 LocalSymbol = nullptr;1197 1198 // Add location debug location. Operands: [Register, 0].1199 dwarf::Attribute Attr =1200 dwarf::Attribute(SymbolKind::S_DEFRANGE_SUBFIELD_REGISTER);1201 uint64_t Operand1 = DefRangeSubfieldRegister.Hdr.Register;1202 1203 LocalVariableAddrRange Range = DefRangeSubfieldRegister.Range;1204 LVAddress Address =1205 Reader->linearAddress(Range.ISectStart, Range.OffsetStart);1206 1207 Symbol->addLocation(Attr, Address, Address + Range.Range, 0, 0);1208 Symbol->addLocationOperands(LVSmall(Attr), {Operand1});1209 }1210 1211 return Error::success();1212}1213 1214// S_DEFRANGE_SUBFIELD1215Error LVSymbolVisitor::visitKnownRecord(CVSymbol &Record,1216 DefRangeSubfieldSym &DefRangeSubfield) {1217 // DefRanges don't have types, just registers and code offsets.1218 LLVM_DEBUG({1219 if (LocalSymbol)1220 W.getOStream() << formatv("Symbol: {0}, ", LocalSymbol->getName());1221 1222 if (ObjDelegate) {1223 DebugStringTableSubsectionRef Strings = ObjDelegate->getStringTable();1224 auto ExpectedProgram = Strings.getString(DefRangeSubfield.Program);1225 if (!ExpectedProgram) {1226 consumeError(ExpectedProgram.takeError());1227 return llvm::make_error<CodeViewError>(1228 "String table offset outside of bounds of String Table!");1229 }1230 W.printString("Program", *ExpectedProgram);1231 }1232 W.printNumber("OffsetInParent", DefRangeSubfield.OffsetInParent);1233 printLocalVariableAddrRange(DefRangeSubfield.Range,1234 DefRangeSubfield.getRelocationOffset());1235 printLocalVariableAddrGap(DefRangeSubfield.Gaps);1236 });1237 1238 if (LVSymbol *Symbol = LocalSymbol) {1239 Symbol->setHasCodeViewLocation();1240 LocalSymbol = nullptr;1241 1242 // Add location debug location. Operands: [Program, 0].1243 dwarf::Attribute Attr = dwarf::Attribute(SymbolKind::S_DEFRANGE_SUBFIELD);1244 uint64_t Operand1 = DefRangeSubfield.Program;1245 1246 LocalVariableAddrRange Range = DefRangeSubfield.Range;1247 LVAddress Address =1248 Reader->linearAddress(Range.ISectStart, Range.OffsetStart);1249 1250 Symbol->addLocation(Attr, Address, Address + Range.Range, 0, 0);1251 Symbol->addLocationOperands(LVSmall(Attr), {Operand1, /*Operand2=*/0});1252 }1253 1254 return Error::success();1255}1256 1257// S_DEFRANGE1258Error LVSymbolVisitor::visitKnownRecord(CVSymbol &Record,1259 DefRangeSym &DefRange) {1260 // DefRanges don't have types, just registers and code offsets.1261 LLVM_DEBUG({1262 if (LocalSymbol)1263 W.getOStream() << formatv("Symbol: {0}, ", LocalSymbol->getName());1264 1265 if (ObjDelegate) {1266 DebugStringTableSubsectionRef Strings = ObjDelegate->getStringTable();1267 auto ExpectedProgram = Strings.getString(DefRange.Program);1268 if (!ExpectedProgram) {1269 consumeError(ExpectedProgram.takeError());1270 return llvm::make_error<CodeViewError>(1271 "String table offset outside of bounds of String Table!");1272 }1273 W.printString("Program", *ExpectedProgram);1274 }1275 printLocalVariableAddrRange(DefRange.Range, DefRange.getRelocationOffset());1276 printLocalVariableAddrGap(DefRange.Gaps);1277 });1278 1279 if (LVSymbol *Symbol = LocalSymbol) {1280 Symbol->setHasCodeViewLocation();1281 LocalSymbol = nullptr;1282 1283 // Add location debug location. Operands: [Program, 0].1284 dwarf::Attribute Attr = dwarf::Attribute(SymbolKind::S_DEFRANGE);1285 uint64_t Operand1 = DefRange.Program;1286 1287 LocalVariableAddrRange Range = DefRange.Range;1288 LVAddress Address =1289 Reader->linearAddress(Range.ISectStart, Range.OffsetStart);1290 1291 Symbol->addLocation(Attr, Address, Address + Range.Range, 0, 0);1292 Symbol->addLocationOperands(LVSmall(Attr), {Operand1, /*Operand2=*/0});1293 }1294 1295 return Error::success();1296}1297 1298// S_FRAMEPROC1299Error LVSymbolVisitor::visitKnownRecord(CVSymbol &Record,1300 FrameProcSym &FrameProc) {1301 if (LVScope *Function = LogicalVisitor->getReaderScope()) {1302 // S_FRAMEPROC contains extra information for the function described1303 // by any of the previous generated records:1304 // S_GPROC32, S_LPROC32, S_LPROC32_ID, S_GPROC32_ID.1305 1306 // The generated sequence is:1307 // S_GPROC32_ID ...1308 // S_FRAMEPROC ...1309 1310 // Collect additional inline flags for the current scope function.1311 FrameProcedureOptions Flags = FrameProc.Flags;1312 if (FrameProcedureOptions::MarkedInline ==1313 (Flags & FrameProcedureOptions::MarkedInline))1314 Function->setInlineCode(dwarf::DW_INL_declared_inlined);1315 if (FrameProcedureOptions::Inlined ==1316 (Flags & FrameProcedureOptions::Inlined))1317 Function->setInlineCode(dwarf::DW_INL_inlined);1318 1319 // To determine the symbol kind for any symbol declared in that function,1320 // we can access the S_FRAMEPROC for the parent scope function. It contains1321 // information about the local fp and param fp registers and compare with1322 // the register in the S_REGREL32 to get a match.1323 codeview::CPUType CPU = Reader->getCompileUnitCPUType();1324 LocalFrameRegister = FrameProc.getLocalFramePtrReg(CPU);1325 ParamFrameRegister = FrameProc.getParamFramePtrReg(CPU);1326 }1327 1328 return Error::success();1329}1330 1331// S_GDATA32, S_LDATA32, S_LMANDATA, S_GMANDATA1332Error LVSymbolVisitor::visitKnownRecord(CVSymbol &Record, DataSym &Data) {1333 LLVM_DEBUG({1334 printTypeIndex("Type", Data.Type);1335 W.printString("DisplayName", Data.Name);1336 });1337 1338 if (LVSymbol *Symbol = LogicalVisitor->CurrentSymbol) {1339 StringRef LinkageName;1340 if (ObjDelegate)1341 ObjDelegate->getLinkageName(Data.getRelocationOffset(), Data.DataOffset,1342 &LinkageName);1343 1344 Symbol->setName(Data.Name);1345 Symbol->setLinkageName(LinkageName);1346 1347 // The MSVC generates local data as initialization for aggregates. It1348 // contains the address for an initialization function.1349 // The symbols contains the '$initializer$' pattern. Allow them only if1350 // the '--internal=system' option is given.1351 // 0 | S_LDATA32 `Struct$initializer$`1352 // type = 0x1040 (void ()*)1353 if (getReader().isSystemEntry(Symbol) && !options().getAttributeSystem()) {1354 Symbol->resetIncludeInPrint();1355 return Error::success();1356 }1357 1358 if (LVScope *Namespace = Shared->NamespaceDeduction.get(Data.Name)) {1359 // The variable is already at different scope. In order to reflect1360 // the correct parent, move it to the namespace.1361 if (Symbol->getParentScope()->removeElement(Symbol))1362 Namespace->addElement(Symbol);1363 }1364 1365 Symbol->setType(LogicalVisitor->getElement(StreamTPI, Data.Type));1366 if (Record.kind() == SymbolKind::S_GDATA32)1367 Symbol->setIsExternal();1368 }1369 1370 return Error::success();1371}1372 1373// S_INLINESITE1374Error LVSymbolVisitor::visitKnownRecord(CVSymbol &Record,1375 InlineSiteSym &InlineSite) {1376 LLVM_DEBUG({ printTypeIndex("Inlinee", InlineSite.Inlinee); });1377 1378 if (LVScope *InlinedFunction = LogicalVisitor->CurrentScope) {1379 LVScope *AbstractFunction = Reader->createScopeFunction();1380 AbstractFunction->setIsSubprogram();1381 AbstractFunction->setTag(dwarf::DW_TAG_subprogram);1382 AbstractFunction->setInlineCode(dwarf::DW_INL_inlined);1383 AbstractFunction->setIsInlinedAbstract();1384 InlinedFunction->setReference(AbstractFunction);1385 1386 LogicalVisitor->startProcessArgumentList();1387 // 'Inlinee' is a Type ID.1388 CVType CVFunctionType = Ids.getType(InlineSite.Inlinee);1389 if (Error Err = LogicalVisitor->finishVisitation(1390 CVFunctionType, InlineSite.Inlinee, AbstractFunction))1391 return Err;1392 LogicalVisitor->stopProcessArgumentList();1393 1394 // For inlined functions set the linkage name to be the same as1395 // the name. It used to find their lines and ranges.1396 StringRef Name = AbstractFunction->getName();1397 InlinedFunction->setName(Name);1398 InlinedFunction->setLinkageName(Name);1399 1400 // Process annotation bytes to calculate code and line offsets.1401 if (Error Err = LogicalVisitor->inlineSiteAnnotation(1402 AbstractFunction, InlinedFunction, InlineSite))1403 return Err;1404 }1405 1406 return Error::success();1407}1408 1409// S_LOCAL1410Error LVSymbolVisitor::visitKnownRecord(CVSymbol &Record, LocalSym &Local) {1411 LLVM_DEBUG({1412 printTypeIndex("Type", Local.Type);1413 W.printFlags("Flags", uint16_t(Local.Flags), getLocalFlagNames());1414 W.printString("VarName", Local.Name);1415 });1416 1417 if (LVSymbol *Symbol = LogicalVisitor->CurrentSymbol) {1418 Symbol->setName(Local.Name);1419 1420 // Symbol was created as 'variable'; determine its real kind.1421 Symbol->resetIsVariable();1422 1423 // Be sure the 'this' symbol is marked as 'compiler generated'.1424 if (bool(Local.Flags & LocalSymFlags::IsCompilerGenerated) ||1425 Local.Name == "this") {1426 Symbol->setIsArtificial();1427 Symbol->setIsParameter();1428 } else {1429 bool(Local.Flags & LocalSymFlags::IsParameter) ? Symbol->setIsParameter()1430 : Symbol->setIsVariable();1431 }1432 1433 // Update correct debug information tag.1434 if (Symbol->getIsParameter())1435 Symbol->setTag(dwarf::DW_TAG_formal_parameter);1436 1437 LVElement *Element = LogicalVisitor->getElement(StreamTPI, Local.Type);1438 if (Element && Element->getIsScoped()) {1439 // We have a local type. Find its parent function.1440 LVScope *Parent = Symbol->getFunctionParent();1441 // The element representing the type has been already finalized. If1442 // the type is an aggregate type, its members have been already added.1443 // As the type is local, its level will be changed.1444 Parent->addElement(Element);1445 Element->updateLevel(Parent);1446 }1447 Symbol->setType(Element);1448 1449 // The CodeView records (S_DEFFRAME_*) describing debug location for1450 // this symbol, do not have any direct reference to it. Those records1451 // are emitted after this symbol. Record the current symbol.1452 LocalSymbol = Symbol;1453 }1454 1455 return Error::success();1456}1457 1458// S_OBJNAME1459Error LVSymbolVisitor::visitKnownRecord(CVSymbol &Record, ObjNameSym &ObjName) {1460 LLVM_DEBUG({1461 W.printHex("Signature", ObjName.Signature);1462 W.printString("ObjectName", ObjName.Name);1463 });1464 1465 CurrentObjectName = ObjName.Name;1466 return Error::success();1467}1468 1469// S_GPROC32, S_LPROC32, S_LPROC32_ID, S_GPROC32_ID1470Error LVSymbolVisitor::visitKnownRecord(CVSymbol &Record, ProcSym &Proc) {1471 if (InFunctionScope)1472 return llvm::make_error<CodeViewError>("Visiting a ProcSym while inside "1473 "function scope!");1474 1475 InFunctionScope = true;1476 1477 LLVM_DEBUG({1478 printTypeIndex("FunctionType", Proc.FunctionType);1479 W.printHex("Segment", Proc.Segment);1480 W.printFlags("Flags", static_cast<uint8_t>(Proc.Flags),1481 getProcSymFlagNames());1482 W.printString("DisplayName", Proc.Name);1483 });1484 1485 // Clang and Microsoft generated different debug information records:1486 // For functions definitions:1487 // Clang: S_GPROC32 -> LF_FUNC_ID -> LF_PROCEDURE1488 // Microsoft: S_GPROC32 -> LF_PROCEDURE1489 1490 // For member function definition:1491 // Clang: S_GPROC32 -> LF_MFUNC_ID -> LF_MFUNCTION1492 // Microsoft: S_GPROC32 -> LF_MFUNCTION1493 // In order to support both sequences, if we found LF_FUNCTION_ID, just1494 // get the TypeIndex for LF_PROCEDURE.1495 1496 // For the given test case, we have the sequence:1497 // namespace NSP_local {1498 // void foo_local() {1499 // }1500 // }1501 //1502 // 0x1000 | LF_STRING_ID String: NSP_local1503 // 0x1002 | LF_PROCEDURE1504 // return type = 0x0003 (void), # args = 0, param list = 0x10011505 // calling conv = cdecl, options = None1506 // 0x1003 | LF_FUNC_ID1507 // name = foo_local, type = 0x1002, parent scope = 0x10001508 // 0 | S_GPROC32_ID `NSP_local::foo_local`1509 // type = `0x1003 (foo_local)`1510 // 0x1004 | LF_STRING_ID String: suite1511 // 0x1005 | LF_STRING_ID String: suite_local.cpp1512 //1513 // The LF_STRING_ID can hold different information:1514 // 0x1000 - The enclosing namespace.1515 // 0x1004 - The compile unit directory name.1516 // 0x1005 - The compile unit name.1517 //1518 // Before deducting its scope, we need to evaluate its type and create any1519 // associated namespaces.1520 if (LVScope *Function = LogicalVisitor->CurrentScope) {1521 StringRef LinkageName;1522 if (ObjDelegate)1523 ObjDelegate->getLinkageName(Proc.getRelocationOffset(), Proc.CodeOffset,1524 &LinkageName);1525 1526 // The line table can be accessed using the linkage name.1527 Reader->addToSymbolTable(LinkageName, Function);1528 Function->setName(Proc.Name);1529 Function->setLinkageName(LinkageName);1530 1531 if (options().getGeneralCollectRanges()) {1532 // Record converted segment::offset addressing for this scope.1533 LVAddress Addendum = Reader->getSymbolTableAddress(LinkageName);1534 LVAddress LowPC =1535 Reader->linearAddress(Proc.Segment, Proc.CodeOffset, Addendum);1536 LVAddress HighPC = LowPC + Proc.CodeSize - 1;1537 Function->addObject(LowPC, HighPC);1538 1539 // If the scope is a function, add it to the public names.1540 if ((options().getAttributePublics() || options().getPrintAnyLine()) &&1541 !Function->getIsInlinedFunction())1542 Reader->getCompileUnit()->addPublicName(Function, LowPC, HighPC);1543 }1544 1545 if (Function->getIsSystem() && !options().getAttributeSystem()) {1546 Function->resetIncludeInPrint();1547 return Error::success();1548 }1549 1550 TypeIndex TIFunctionType = Proc.FunctionType;1551 if (TIFunctionType.isSimple())1552 Function->setType(LogicalVisitor->getElement(StreamTPI, TIFunctionType));1553 else {1554 // We have to detect the correct stream, using the lexical parent1555 // name, as there is not other obvious way to get the stream.1556 // Normal function: LF_FUNC_ID (TPI)/(IPI)1557 // LF_PROCEDURE (TPI)1558 // Lambda function: LF_MFUNCTION (TPI)1559 // Member function: LF_MFUNC_ID (TPI)/(IPI)1560 1561 StringRef OuterComponent;1562 std::tie(OuterComponent, std::ignore) = getInnerComponent(Proc.Name);1563 TypeIndex TI = Shared->ForwardReferences.find(OuterComponent);1564 1565 std::optional<CVType> CVFunctionType;1566 auto GetRecordType = [&]() -> bool {1567 CVFunctionType = Ids.tryGetType(TIFunctionType);1568 if (!CVFunctionType)1569 return false;1570 1571 if (TI.isNoneType())1572 // Normal function.1573 if (CVFunctionType->kind() == LF_FUNC_ID)1574 return true;1575 1576 // Member function.1577 return (CVFunctionType->kind() == LF_MFUNC_ID);1578 };1579 1580 // We can have a LF_FUNC_ID, LF_PROCEDURE or LF_MFUNCTION.1581 if (!GetRecordType()) {1582 CVFunctionType = Types.tryGetType(TIFunctionType);1583 if (!CVFunctionType)1584 return llvm::make_error<CodeViewError>("Invalid type index");1585 }1586 1587 if (Error Err = LogicalVisitor->finishVisitation(1588 *CVFunctionType, TIFunctionType, Function))1589 return Err;1590 }1591 1592 if (Record.kind() == SymbolKind::S_GPROC32 ||1593 Record.kind() == SymbolKind::S_GPROC32_ID)1594 Function->setIsExternal();1595 1596 // We don't have a way to see if the symbol is compiler generated. Use1597 // the linkage name, to detect `scalar deleting destructor' functions.1598 std::string DemangledSymbol = demangle(LinkageName);1599 if (DemangledSymbol.find("scalar deleting dtor") != std::string::npos) {1600 Function->setIsArtificial();1601 } else {1602 // Clang generates global ctor and dtor names containing the substrings:1603 // 'dynamic initializer for' and 'dynamic atexit destructor for'.1604 if (DemangledSymbol.find("dynamic atexit destructor for") !=1605 std::string::npos)1606 Function->setIsArtificial();1607 }1608 }1609 1610 return Error::success();1611}1612 1613// S_END1614Error LVSymbolVisitor::visitKnownRecord(CVSymbol &Record,1615 ScopeEndSym &ScopeEnd) {1616 InFunctionScope = false;1617 return Error::success();1618}1619 1620// S_THUNK321621Error LVSymbolVisitor::visitKnownRecord(CVSymbol &Record, Thunk32Sym &Thunk) {1622 if (InFunctionScope)1623 return llvm::make_error<CodeViewError>("Visiting a Thunk32Sym while inside "1624 "function scope!");1625 1626 InFunctionScope = true;1627 1628 LLVM_DEBUG({1629 W.printHex("Segment", Thunk.Segment);1630 W.printString("Name", Thunk.Name);1631 });1632 1633 if (LVScope *Function = LogicalVisitor->CurrentScope)1634 Function->setName(Thunk.Name);1635 1636 return Error::success();1637}1638 1639// S_UDT, S_COBOLUDT1640Error LVSymbolVisitor::visitKnownRecord(CVSymbol &Record, UDTSym &UDT) {1641 LLVM_DEBUG({1642 printTypeIndex("Type", UDT.Type);1643 W.printString("UDTName", UDT.Name);1644 });1645 1646 if (LVType *Type = LogicalVisitor->CurrentType) {1647 if (LVScope *Namespace = Shared->NamespaceDeduction.get(UDT.Name)) {1648 if (Type->getParentScope()->removeElement(Type))1649 Namespace->addElement(Type);1650 }1651 1652 Type->setName(UDT.Name);1653 1654 // We have to determine if the typedef is a real C/C++ definition or is1655 // the S_UDT record that describe all the user defined types.1656 // 0 | S_UDT `Name` original type = 0x10091657 // 0x1009 | LF_STRUCTURE `Name`1658 // Ignore type definitions for RTTI types:1659 // _s__RTTIBaseClassArray, _s__RTTIBaseClassDescriptor,1660 // _s__RTTICompleteObjectLocator, _s__RTTIClassHierarchyDescriptor.1661 if (getReader().isSystemEntry(Type))1662 Type->resetIncludeInPrint();1663 else {1664 StringRef RecordName = getRecordName(Types, UDT.Type);1665 if (UDT.Name == RecordName)1666 Type->resetIncludeInPrint();1667 Type->setType(LogicalVisitor->getElement(StreamTPI, UDT.Type));1668 }1669 }1670 1671 return Error::success();1672}1673 1674// S_UNAMESPACE1675Error LVSymbolVisitor::visitKnownRecord(CVSymbol &Record,1676 UsingNamespaceSym &UN) {1677 LLVM_DEBUG({ W.printString("Namespace", UN.Name); });1678 return Error::success();1679}1680 1681// S_ARMSWITCHTABLE1682Error LVSymbolVisitor::visitKnownRecord(CVSymbol &CVR,1683 JumpTableSym &JumpTable) {1684 LLVM_DEBUG({1685 W.printHex("BaseOffset", JumpTable.BaseOffset);1686 W.printNumber("BaseSegment", JumpTable.BaseSegment);1687 W.printFlags("SwitchType", static_cast<uint16_t>(JumpTable.SwitchType),1688 getJumpTableEntrySizeNames());1689 W.printHex("BranchOffset", JumpTable.BranchOffset);1690 W.printHex("TableOffset", JumpTable.TableOffset);1691 W.printNumber("BranchSegment", JumpTable.BranchSegment);1692 W.printNumber("TableSegment", JumpTable.TableSegment);1693 W.printNumber("EntriesCount", JumpTable.EntriesCount);1694 });1695 return Error::success();1696}1697 1698// S_CALLERS, S_CALLEES, S_INLINEES1699Error LVSymbolVisitor::visitKnownRecord(CVSymbol &Record, CallerSym &Caller) {1700 LLVM_DEBUG({1701 llvm::StringRef FieldName;1702 switch (Caller.getKind()) {1703 case SymbolRecordKind::CallerSym:1704 FieldName = "Callee";1705 break;1706 case SymbolRecordKind::CalleeSym:1707 FieldName = "Caller";1708 break;1709 case SymbolRecordKind::InlineesSym:1710 FieldName = "Inlinee";1711 break;1712 default:1713 return llvm::make_error<CodeViewError>(1714 "Unknown CV Record type for a CallerSym object!");1715 }1716 for (auto FuncID : Caller.Indices) {1717 printTypeIndex(FieldName, FuncID);1718 }1719 });1720 return Error::success();1721}1722 1723#undef DEBUG_TYPE1724#define DEBUG_TYPE "CodeViewLogicalVisitor"1725 1726//===----------------------------------------------------------------------===//1727// Logical visitor.1728//===----------------------------------------------------------------------===//1729LVLogicalVisitor::LVLogicalVisitor(LVCodeViewReader *Reader, ScopedPrinter &W,1730 InputFile &Input)1731 : Reader(Reader), W(W), Input(Input) {1732 // The LogicalVisitor connects the CodeViewReader with the visitors that1733 // traverse the types, symbols, etc. Do any initialization that is needed.1734 Shared = std::make_shared<LVShared>(Reader, this);1735}1736 1737void LVLogicalVisitor::printTypeIndex(StringRef FieldName, TypeIndex TI,1738 uint32_t StreamIdx) {1739 codeview::printTypeIndex(W, FieldName, TI,1740 StreamIdx == StreamTPI ? types() : ids());1741}1742 1743void LVLogicalVisitor::printTypeBegin(CVType &Record, TypeIndex TI,1744 LVElement *Element, uint32_t StreamIdx) {1745 W.getOStream() << "\n";1746 W.startLine() << formatTypeLeafKind(Record.kind());1747 W.getOStream() << " (" << HexNumber(TI.getIndex()) << ")";1748 W.getOStream() << " {\n";1749 W.indent();1750 W.printEnum("TypeLeafKind", unsigned(Record.kind()), ArrayRef(LeafTypeNames));1751 printTypeIndex("TI", TI, StreamIdx);1752 W.startLine() << "Element: " << HexNumber(Element->getOffset()) << " "1753 << Element->getName() << "\n";1754}1755 1756void LVLogicalVisitor::printTypeEnd(CVType &Record) {1757 W.unindent();1758 W.startLine() << "}\n";1759}1760 1761void LVLogicalVisitor::printMemberBegin(CVMemberRecord &Record, TypeIndex TI,1762 LVElement *Element,1763 uint32_t StreamIdx) {1764 W.getOStream() << "\n";1765 W.startLine() << formatTypeLeafKind(Record.Kind);1766 W.getOStream() << " (" << HexNumber(TI.getIndex()) << ")";1767 W.getOStream() << " {\n";1768 W.indent();1769 W.printEnum("TypeLeafKind", unsigned(Record.Kind), ArrayRef(LeafTypeNames));1770 printTypeIndex("TI", TI, StreamIdx);1771 W.startLine() << "Element: " << HexNumber(Element->getOffset()) << " "1772 << Element->getName() << "\n";1773}1774 1775void LVLogicalVisitor::printMemberEnd(CVMemberRecord &Record) {1776 W.unindent();1777 W.startLine() << "}\n";1778}1779 1780Error LVLogicalVisitor::visitUnknownType(CVType &Record, TypeIndex TI) {1781 LLVM_DEBUG({1782 printTypeIndex("\nTI", TI, StreamTPI);1783 W.printNumber("Length", uint32_t(Record.content().size()));1784 });1785 return Error::success();1786}1787 1788// LF_ARGLIST (TPI)1789Error LVLogicalVisitor::visitKnownRecord(CVType &Record, ArgListRecord &Args,1790 TypeIndex TI, LVElement *Element) {1791 ArrayRef<TypeIndex> Indices = Args.getIndices();1792 uint32_t Size = Indices.size();1793 LLVM_DEBUG({1794 printTypeBegin(Record, TI, Element, StreamTPI);1795 W.printNumber("NumArgs", Size);1796 ListScope Arguments(W, "Arguments");1797 for (uint32_t I = 0; I < Size; ++I)1798 printTypeIndex("ArgType", Indices[I], StreamTPI);1799 printTypeEnd(Record);1800 });1801 1802 LVScope *Function = static_cast<LVScope *>(Element);1803 for (uint32_t Index = 0; Index < Size; ++Index) {1804 TypeIndex ParameterType = Indices[Index];1805 createParameter(ParameterType, StringRef(), Function);1806 }1807 1808 return Error::success();1809}1810 1811// LF_ARRAY (TPI)1812Error LVLogicalVisitor::visitKnownRecord(CVType &Record, ArrayRecord &AT,1813 TypeIndex TI, LVElement *Element) {1814 LLVM_DEBUG({1815 printTypeBegin(Record, TI, Element, StreamTPI);1816 printTypeIndex("ElementType", AT.getElementType(), StreamTPI);1817 printTypeIndex("IndexType", AT.getIndexType(), StreamTPI);1818 W.printNumber("SizeOf", AT.getSize());1819 W.printString("Name", AT.getName());1820 printTypeEnd(Record);1821 });1822 1823 if (Element->getIsFinalized())1824 return Error::success();1825 Element->setIsFinalized();1826 1827 LVScopeArray *Array = static_cast<LVScopeArray *>(Element);1828 if (!Array)1829 return Error::success();1830 1831 Reader->getCompileUnit()->addElement(Array);1832 TypeIndex TIElementType = AT.getElementType();1833 1834 LVType *PrevSubrange = nullptr;1835 LazyRandomTypeCollection &Types = types();1836 1837 // As the logical view is modeled on DWARF, for each dimension we have to1838 // create a DW_TAG_subrange_type, with dimension size.1839 // The subrange type can be: unsigned __int32 or unsigned __int64.1840 auto AddSubrangeType = [&](ArrayRecord &AR) {1841 LVType *Subrange = Reader->createTypeSubrange();1842 Subrange->setTag(dwarf::DW_TAG_subrange_type);1843 Subrange->setType(getElement(StreamTPI, AR.getIndexType()));1844 Subrange->setCount(AR.getSize());1845 Subrange->setOffset(1846 TIElementType.isSimple()1847 ? (uint32_t)(TypeLeafKind)TIElementType.getSimpleKind()1848 : TIElementType.getIndex());1849 Array->addElement(Subrange);1850 1851 if (PrevSubrange)1852 if (int64_t Count = Subrange->getCount())1853 PrevSubrange->setCount(PrevSubrange->getCount() / Count);1854 PrevSubrange = Subrange;1855 };1856 1857 // Preserve the original TypeIndex; it would be updated in the case of:1858 // - The array type contains qualifiers.1859 // - In multidimensional arrays, the last LF_ARRAY entry contains the type.1860 TypeIndex TIArrayType;1861 1862 // For each dimension in the array, there is a LF_ARRAY entry. The last1863 // entry contains the array type, which can be a LF_MODIFIER in the case1864 // of the type being modified by a qualifier (const, etc).1865 ArrayRecord AR(AT);1866 CVType CVEntry = Record;1867 while (CVEntry.kind() == LF_ARRAY) {1868 // Create the subrange information, required by the logical view. Once1869 // the array has been processed, the dimension sizes will updated, as1870 // the sizes are a progression. For instance:1871 // sizeof(int) = 41872 // int Array[2]; Sizes: 8 Dim: 8 / 4 -> [2]1873 // int Array[2][3]; Sizes: 24, 12 Dim: 24 / 12 -> [2]1874 // Dim: 12 / 4 -> [3]1875 // int Array[2][3][4]; sizes: 96, 48, 16 Dim: 96 / 48 -> [2]1876 // Dim: 48 / 16 -> [3]1877 // Dim: 16 / 4 -> [4]1878 AddSubrangeType(AR);1879 TIArrayType = TIElementType;1880 1881 // The current ElementType can be a modifier, in which case we need to1882 // get the type being modified.1883 // If TypeIndex is not a simple type, check if we have a qualified type.1884 if (!TIElementType.isSimple()) {1885 CVType CVElementType = Types.getType(TIElementType);1886 if (CVElementType.kind() == LF_MODIFIER) {1887 LVElement *QualifiedType =1888 Shared->TypeRecords.find(StreamTPI, TIElementType);1889 if (Error Err =1890 finishVisitation(CVElementType, TIElementType, QualifiedType))1891 return Err;1892 // Get the TypeIndex of the type that the LF_MODIFIER modifies.1893 TIElementType = getModifiedType(CVElementType);1894 }1895 }1896 // Ends the traversal, as we have reached a simple type (int, char, etc).1897 if (TIElementType.isSimple())1898 break;1899 1900 // Read next dimension linked entry, if any.1901 CVEntry = Types.getType(TIElementType);1902 if (Error Err = TypeDeserializer::deserializeAs(1903 const_cast<CVType &>(CVEntry), AR)) {1904 consumeError(std::move(Err));1905 break;1906 }1907 TIElementType = AR.getElementType();1908 // NOTE: The typeindex has a value of: 0x0280.00001909 getTrueType(TIElementType);1910 }1911 1912 Array->setName(AT.getName());1913 TIArrayType = Shared->ForwardReferences.remap(TIArrayType);1914 Array->setType(getElement(StreamTPI, TIArrayType));1915 1916 if (PrevSubrange)1917 // In the case of an aggregate type (class, struct, union, interface),1918 // get the aggregate size. As the original record is pointing to its1919 // reference, we have to update it.1920 if (uint64_t Size =1921 isAggregate(CVEntry)1922 ? getSizeInBytesForTypeRecord(Types.getType(TIArrayType))1923 : getSizeInBytesForTypeIndex(TIElementType))1924 PrevSubrange->setCount(PrevSubrange->getCount() / Size);1925 1926 return Error::success();1927}1928 1929// LF_BITFIELD (TPI)1930Error LVLogicalVisitor::visitKnownRecord(CVType &Record, BitFieldRecord &BF,1931 TypeIndex TI, LVElement *Element) {1932 LLVM_DEBUG({1933 printTypeBegin(Record, TI, Element, StreamTPI);1934 printTypeIndex("Type", TI, StreamTPI);1935 W.printNumber("BitSize", BF.getBitSize());1936 W.printNumber("BitOffset", BF.getBitOffset());1937 printTypeEnd(Record);1938 });1939 1940 Element->setType(getElement(StreamTPI, BF.getType()));1941 Element->setBitSize(BF.getBitSize());1942 return Error::success();1943}1944 1945// LF_BUILDINFO (TPI)/(IPI)1946Error LVLogicalVisitor::visitKnownRecord(CVType &Record, BuildInfoRecord &BI,1947 TypeIndex TI, LVElement *Element) {1948 LLVM_DEBUG({1949 printTypeBegin(Record, TI, Element, StreamIPI);1950 W.printNumber("NumArgs", static_cast<uint32_t>(BI.getArgs().size()));1951 ListScope Arguments(W, "Arguments");1952 for (TypeIndex Arg : BI.getArgs())1953 printTypeIndex("ArgType", Arg, StreamIPI);1954 printTypeEnd(Record);1955 });1956 1957 // The given 'Element' refers to the current compilation unit.1958 // All the args are references into the TPI/IPI stream.1959 TypeIndex TIName = BI.getArgs()[BuildInfoRecord::BuildInfoArg::SourceFile];1960 std::string Name = std::string(ids().getTypeName(TIName));1961 1962 // There are cases where LF_BUILDINFO fields are empty.1963 if (!Name.empty())1964 Element->setName(Name);1965 1966 return Error::success();1967}1968 1969// LF_CLASS, LF_STRUCTURE, LF_INTERFACE (TPI)1970Error LVLogicalVisitor::visitKnownRecord(CVType &Record, ClassRecord &Class,1971 TypeIndex TI, LVElement *Element) {1972 LLVM_DEBUG({1973 printTypeBegin(Record, TI, Element, StreamTPI);1974 W.printNumber("MemberCount", Class.getMemberCount());1975 printTypeIndex("FieldList", Class.getFieldList(), StreamTPI);1976 printTypeIndex("DerivedFrom", Class.getDerivationList(), StreamTPI);1977 printTypeIndex("VShape", Class.getVTableShape(), StreamTPI);1978 W.printNumber("SizeOf", Class.getSize());1979 W.printString("Name", Class.getName());1980 if (Class.hasUniqueName())1981 W.printString("UniqueName", Class.getUniqueName());1982 printTypeEnd(Record);1983 });1984 1985 if (Element->getIsFinalized())1986 return Error::success();1987 Element->setIsFinalized();1988 1989 LVScopeAggregate *Scope = static_cast<LVScopeAggregate *>(Element);1990 if (!Scope)1991 return Error::success();1992 1993 Scope->setName(Class.getName());1994 if (Class.hasUniqueName())1995 Scope->setLinkageName(Class.getUniqueName());1996 Scope->setBitSize(Class.getSize() * DWARF_CHAR_BIT);1997 1998 if (Class.isNested()) {1999 Scope->setIsNested();2000 createParents(Class.getName(), Scope);2001 }2002 2003 if (Class.isScoped())2004 Scope->setIsScoped();2005 2006 // Nested types will be added to their parents at creation. The forward2007 // references are only processed to finish the referenced element creation.2008 if (!(Class.isNested() || Class.isScoped())) {2009 if (LVScope *Namespace = Shared->NamespaceDeduction.get(Class.getName()))2010 Namespace->addElement(Scope);2011 else2012 Reader->getCompileUnit()->addElement(Scope);2013 }2014 2015 LazyRandomTypeCollection &Types = types();2016 TypeIndex TIFieldList = Class.getFieldList();2017 if (TIFieldList.isNoneType()) {2018 TypeIndex ForwardType = Shared->ForwardReferences.find(Class.getName());2019 if (!ForwardType.isNoneType()) {2020 CVType CVReference = Types.getType(ForwardType);2021 TypeRecordKind RK = static_cast<TypeRecordKind>(CVReference.kind());2022 ClassRecord ReferenceRecord(RK);2023 if (Error Err = TypeDeserializer::deserializeAs(2024 const_cast<CVType &>(CVReference), ReferenceRecord))2025 return Err;2026 TIFieldList = ReferenceRecord.getFieldList();2027 }2028 }2029 2030 if (!TIFieldList.isNoneType()) {2031 // Pass down the TypeIndex 'TI' for the aggregate containing the field list.2032 CVType CVFieldList = Types.getType(TIFieldList);2033 if (Error Err = finishVisitation(CVFieldList, TI, Scope))2034 return Err;2035 }2036 2037 return Error::success();2038}2039 2040// LF_ENUM (TPI)2041Error LVLogicalVisitor::visitKnownRecord(CVType &Record, EnumRecord &Enum,2042 TypeIndex TI, LVElement *Element) {2043 LLVM_DEBUG({2044 printTypeBegin(Record, TI, Element, StreamTPI);2045 W.printNumber("NumEnumerators", Enum.getMemberCount());2046 printTypeIndex("UnderlyingType", Enum.getUnderlyingType(), StreamTPI);2047 printTypeIndex("FieldListType", Enum.getFieldList(), StreamTPI);2048 W.printString("Name", Enum.getName());2049 printTypeEnd(Record);2050 });2051 2052 LVScopeEnumeration *Scope = static_cast<LVScopeEnumeration *>(Element);2053 if (!Scope)2054 return Error::success();2055 2056 if (Scope->getIsFinalized())2057 return Error::success();2058 Scope->setIsFinalized();2059 2060 // Set the name, as in the case of nested, it would determine the relation2061 // to any potential parent, via the LF_NESTTYPE record.2062 Scope->setName(Enum.getName());2063 if (Enum.hasUniqueName())2064 Scope->setLinkageName(Enum.getUniqueName());2065 2066 Scope->setType(getElement(StreamTPI, Enum.getUnderlyingType()));2067 2068 if (Enum.isNested()) {2069 Scope->setIsNested();2070 createParents(Enum.getName(), Scope);2071 }2072 2073 if (Enum.isScoped()) {2074 Scope->setIsScoped();2075 Scope->setIsEnumClass();2076 }2077 2078 // Nested types will be added to their parents at creation.2079 if (!(Enum.isNested() || Enum.isScoped())) {2080 if (LVScope *Namespace = Shared->NamespaceDeduction.get(Enum.getName()))2081 Namespace->addElement(Scope);2082 else2083 Reader->getCompileUnit()->addElement(Scope);2084 }2085 2086 TypeIndex TIFieldList = Enum.getFieldList();2087 if (!TIFieldList.isNoneType()) {2088 LazyRandomTypeCollection &Types = types();2089 CVType CVFieldList = Types.getType(TIFieldList);2090 if (Error Err = finishVisitation(CVFieldList, TIFieldList, Scope))2091 return Err;2092 }2093 2094 return Error::success();2095}2096 2097// LF_FIELDLIST (TPI)2098Error LVLogicalVisitor::visitKnownRecord(CVType &Record,2099 FieldListRecord &FieldList,2100 TypeIndex TI, LVElement *Element) {2101 LLVM_DEBUG({2102 printTypeBegin(Record, TI, Element, StreamTPI);2103 printTypeEnd(Record);2104 });2105 2106 if (Error Err = visitFieldListMemberStream(TI, Element, FieldList.Data))2107 return Err;2108 2109 return Error::success();2110}2111 2112// LF_FUNC_ID (TPI)/(IPI)2113Error LVLogicalVisitor::visitKnownRecord(CVType &Record, FuncIdRecord &Func,2114 TypeIndex TI, LVElement *Element) {2115 // ParentScope and FunctionType are references into the TPI stream.2116 LLVM_DEBUG({2117 printTypeBegin(Record, TI, Element, StreamIPI);2118 printTypeIndex("ParentScope", Func.getParentScope(), StreamTPI);2119 printTypeIndex("FunctionType", Func.getFunctionType(), StreamTPI);2120 W.printString("Name", Func.getName());2121 printTypeEnd(Record);2122 });2123 2124 // The TypeIndex (LF_PROCEDURE) returned by 'getFunctionType' is the2125 // function propotype, we need to use the function definition.2126 if (LVScope *FunctionDcl = static_cast<LVScope *>(Element)) {2127 // For inlined functions, the inlined instance has been already processed2128 // (all its information is contained in the Symbols section).2129 // 'Element' points to the created 'abstract' (out-of-line) function.2130 // Use the parent scope information to allocate it to the correct scope.2131 LazyRandomTypeCollection &Types = types();2132 TypeIndex TIParent = Func.getParentScope();2133 if (FunctionDcl->getIsInlinedAbstract()) {2134 FunctionDcl->setName(Func.getName());2135 if (TIParent.isNoneType())2136 Reader->getCompileUnit()->addElement(FunctionDcl);2137 }2138 2139 if (!TIParent.isNoneType()) {2140 CVType CVParentScope = ids().getType(TIParent);2141 if (Error Err = finishVisitation(CVParentScope, TIParent, FunctionDcl))2142 return Err;2143 }2144 2145 TypeIndex TIFunctionType = Func.getFunctionType();2146 CVType CVFunctionType = Types.getType(TIFunctionType);2147 if (Error Err =2148 finishVisitation(CVFunctionType, TIFunctionType, FunctionDcl))2149 return Err;2150 2151 FunctionDcl->setIsFinalized();2152 }2153 2154 return Error::success();2155}2156 2157// LF_LABEL (TPI)2158Error LVLogicalVisitor::visitKnownRecord(CVType &Record, LabelRecord &LR,2159 TypeIndex TI, LVElement *Element) {2160 LLVM_DEBUG({2161 printTypeBegin(Record, TI, Element, StreamTPI);2162 printTypeEnd(Record);2163 });2164 return Error::success();2165}2166 2167// LF_MFUNC_ID (TPI)/(IPI)2168Error LVLogicalVisitor::visitKnownRecord(CVType &Record, MemberFuncIdRecord &Id,2169 TypeIndex TI, LVElement *Element) {2170 // ClassType and FunctionType are references into the TPI stream.2171 LLVM_DEBUG({2172 printTypeBegin(Record, TI, Element, StreamIPI);2173 printTypeIndex("ClassType", Id.getClassType(), StreamTPI);2174 printTypeIndex("FunctionType", Id.getFunctionType(), StreamTPI);2175 W.printString("Name", Id.getName());2176 printTypeEnd(Record);2177 });2178 2179 LVScope *FunctionDcl = static_cast<LVScope *>(Element);2180 if (FunctionDcl->getIsInlinedAbstract()) {2181 // For inlined functions, the inlined instance has been already processed2182 // (all its information is contained in the Symbols section).2183 // 'Element' points to the created 'abstract' (out-of-line) function.2184 // Use the parent scope information to allocate it to the correct scope.2185 if (LVScope *Class = static_cast<LVScope *>(2186 Shared->TypeRecords.find(StreamTPI, Id.getClassType())))2187 Class->addElement(FunctionDcl);2188 }2189 2190 TypeIndex TIFunctionType = Id.getFunctionType();2191 CVType CVFunction = types().getType(TIFunctionType);2192 if (Error Err = finishVisitation(CVFunction, TIFunctionType, Element))2193 return Err;2194 2195 return Error::success();2196}2197 2198// LF_MFUNCTION (TPI)2199Error LVLogicalVisitor::visitKnownRecord(CVType &Record,2200 MemberFunctionRecord &MF, TypeIndex TI,2201 LVElement *Element) {2202 LLVM_DEBUG({2203 printTypeBegin(Record, TI, Element, StreamTPI);2204 printTypeIndex("ReturnType", MF.getReturnType(), StreamTPI);2205 printTypeIndex("ClassType", MF.getClassType(), StreamTPI);2206 printTypeIndex("ThisType", MF.getThisType(), StreamTPI);2207 W.printNumber("NumParameters", MF.getParameterCount());2208 printTypeIndex("ArgListType", MF.getArgumentList(), StreamTPI);2209 W.printNumber("ThisAdjustment", MF.getThisPointerAdjustment());2210 printTypeEnd(Record);2211 });2212 2213 if (LVScope *MemberFunction = static_cast<LVScope *>(Element)) {2214 LVElement *Class = getElement(StreamTPI, MF.getClassType());2215 2216 MemberFunction->setIsFinalized();2217 MemberFunction->setType(getElement(StreamTPI, MF.getReturnType()));2218 MemberFunction->setOffset(TI.getIndex());2219 MemberFunction->setOffsetFromTypeIndex();2220 2221 if (ProcessArgumentList) {2222 ProcessArgumentList = false;2223 2224 if (!MemberFunction->getIsStatic()) {2225 LVElement *ThisPointer = getElement(StreamTPI, MF.getThisType());2226 // When creating the 'this' pointer, check if it points to a reference.2227 ThisPointer->setType(Class);2228 LVSymbol *This =2229 createParameter(ThisPointer, StringRef(), MemberFunction);2230 This->setIsArtificial();2231 }2232 2233 // Create formal parameters.2234 LazyRandomTypeCollection &Types = types();2235 CVType CVArguments = Types.getType(MF.getArgumentList());2236 if (Error Err = finishVisitation(CVArguments, MF.getArgumentList(),2237 MemberFunction))2238 return Err;2239 }2240 }2241 2242 return Error::success();2243}2244 2245// LF_METHODLIST (TPI)2246Error LVLogicalVisitor::visitKnownRecord(CVType &Record,2247 MethodOverloadListRecord &Overloads,2248 TypeIndex TI, LVElement *Element) {2249 LLVM_DEBUG({2250 printTypeBegin(Record, TI, Element, StreamTPI);2251 printTypeEnd(Record);2252 });2253 2254 for (OneMethodRecord &Method : Overloads.Methods) {2255 CVMemberRecord Record;2256 Record.Kind = LF_METHOD;2257 Method.Name = OverloadedMethodName;2258 if (Error Err = visitKnownMember(Record, Method, TI, Element))2259 return Err;2260 }2261 2262 return Error::success();2263}2264 2265// LF_MODIFIER (TPI)2266Error LVLogicalVisitor::visitKnownRecord(CVType &Record, ModifierRecord &Mod,2267 TypeIndex TI, LVElement *Element) {2268 LLVM_DEBUG({2269 printTypeBegin(Record, TI, Element, StreamTPI);2270 printTypeIndex("ModifiedType", Mod.getModifiedType(), StreamTPI);2271 printTypeEnd(Record);2272 });2273 2274 // Create the modified type, which will be attached to the type(s) that2275 // contains the modifiers.2276 LVElement *ModifiedType = getElement(StreamTPI, Mod.getModifiedType());2277 2278 // At this point the types recording the qualifiers do not have a2279 // scope parent. They must be assigned to the current compile unit.2280 LVScopeCompileUnit *CompileUnit = Reader->getCompileUnit();2281 2282 // The incoming element does not have a defined kind. Use the given2283 // modifiers to complete its type. A type can have more than one modifier;2284 // in that case, we have to create an extra type to have the other modifier.2285 LVType *LastLink = static_cast<LVType *>(Element);2286 if (!LastLink->getParentScope())2287 CompileUnit->addElement(LastLink);2288 2289 bool SeenModifier = false;2290 uint16_t Mods = static_cast<uint16_t>(Mod.getModifiers());2291 if (Mods & uint16_t(ModifierOptions::Const)) {2292 SeenModifier = true;2293 LastLink->setTag(dwarf::DW_TAG_const_type);2294 LastLink->setIsConst();2295 LastLink->setName("const");2296 }2297 if (Mods & uint16_t(ModifierOptions::Volatile)) {2298 if (SeenModifier) {2299 LVType *Volatile = Reader->createType();2300 Volatile->setIsModifier();2301 LastLink->setType(Volatile);2302 LastLink = Volatile;2303 CompileUnit->addElement(LastLink);2304 }2305 LastLink->setTag(dwarf::DW_TAG_volatile_type);2306 LastLink->setIsVolatile();2307 LastLink->setName("volatile");2308 }2309 if (Mods & uint16_t(ModifierOptions::Unaligned)) {2310 if (SeenModifier) {2311 LVType *Unaligned = Reader->createType();2312 Unaligned->setIsModifier();2313 LastLink->setType(Unaligned);2314 LastLink = Unaligned;2315 CompileUnit->addElement(LastLink);2316 }2317 LastLink->setTag(dwarf::DW_TAG_unaligned);2318 LastLink->setIsUnaligned();2319 LastLink->setName("unaligned");2320 }2321 2322 LastLink->setType(ModifiedType);2323 return Error::success();2324}2325 2326// LF_POINTER (TPI)2327Error LVLogicalVisitor::visitKnownRecord(CVType &Record, PointerRecord &Ptr,2328 TypeIndex TI, LVElement *Element) {2329 LLVM_DEBUG({2330 printTypeBegin(Record, TI, Element, StreamTPI);2331 printTypeIndex("PointeeType", Ptr.getReferentType(), StreamTPI);2332 W.printNumber("IsFlat", Ptr.isFlat());2333 W.printNumber("IsConst", Ptr.isConst());2334 W.printNumber("IsVolatile", Ptr.isVolatile());2335 W.printNumber("IsUnaligned", Ptr.isUnaligned());2336 W.printNumber("IsRestrict", Ptr.isRestrict());2337 W.printNumber("IsThisPtr&", Ptr.isLValueReferenceThisPtr());2338 W.printNumber("IsThisPtr&&", Ptr.isRValueReferenceThisPtr());2339 W.printNumber("SizeOf", Ptr.getSize());2340 2341 if (Ptr.isPointerToMember()) {2342 const MemberPointerInfo &MI = Ptr.getMemberInfo();2343 printTypeIndex("ClassType", MI.getContainingType(), StreamTPI);2344 }2345 printTypeEnd(Record);2346 });2347 2348 // Find the pointed-to type.2349 LVType *Pointer = static_cast<LVType *>(Element);2350 LVElement *Pointee = nullptr;2351 2352 PointerMode Mode = Ptr.getMode();2353 Pointee = Ptr.isPointerToMember()2354 ? Shared->TypeRecords.find(StreamTPI, Ptr.getReferentType())2355 : getElement(StreamTPI, Ptr.getReferentType());2356 2357 // At this point the types recording the qualifiers do not have a2358 // scope parent. They must be assigned to the current compile unit.2359 LVScopeCompileUnit *CompileUnit = Reader->getCompileUnit();2360 2361 // Order for the different modifiers:2362 // <restrict> <pointer, Reference, ValueReference> <const, volatile>2363 // Const and volatile already processed.2364 bool SeenModifier = false;2365 LVType *LastLink = Pointer;2366 if (!LastLink->getParentScope())2367 CompileUnit->addElement(LastLink);2368 2369 if (Ptr.isRestrict()) {2370 SeenModifier = true;2371 LVType *Restrict = Reader->createType();2372 Restrict->setTag(dwarf::DW_TAG_restrict_type);2373 Restrict->setIsRestrict();2374 Restrict->setName("restrict");2375 LastLink->setType(Restrict);2376 LastLink = Restrict;2377 CompileUnit->addElement(LastLink);2378 }2379 if (Mode == PointerMode::LValueReference) {2380 if (SeenModifier) {2381 LVType *LReference = Reader->createType();2382 LReference->setIsModifier();2383 LastLink->setType(LReference);2384 LastLink = LReference;2385 CompileUnit->addElement(LastLink);2386 }2387 LastLink->setTag(dwarf::DW_TAG_reference_type);2388 LastLink->setIsReference();2389 LastLink->setName("&");2390 }2391 if (Mode == PointerMode::RValueReference) {2392 if (SeenModifier) {2393 LVType *RReference = Reader->createType();2394 RReference->setIsModifier();2395 LastLink->setType(RReference);2396 LastLink = RReference;2397 CompileUnit->addElement(LastLink);2398 }2399 LastLink->setTag(dwarf::DW_TAG_rvalue_reference_type);2400 LastLink->setIsRvalueReference();2401 LastLink->setName("&&");2402 }2403 2404 // When creating the pointer, check if it points to a reference.2405 LastLink->setType(Pointee);2406 return Error::success();2407}2408 2409// LF_PROCEDURE (TPI)2410Error LVLogicalVisitor::visitKnownRecord(CVType &Record, ProcedureRecord &Proc,2411 TypeIndex TI, LVElement *Element) {2412 LLVM_DEBUG({2413 printTypeBegin(Record, TI, Element, StreamTPI);2414 printTypeIndex("ReturnType", Proc.getReturnType(), StreamTPI);2415 W.printNumber("NumParameters", Proc.getParameterCount());2416 printTypeIndex("ArgListType", Proc.getArgumentList(), StreamTPI);2417 printTypeEnd(Record);2418 });2419 2420 // There is no need to traverse the argument list, as the CodeView format2421 // declares the parameters as a 'S_LOCAL' symbol tagged as parameter.2422 // Only process parameters when dealing with inline functions.2423 if (LVScope *FunctionDcl = static_cast<LVScope *>(Element)) {2424 FunctionDcl->setType(getElement(StreamTPI, Proc.getReturnType()));2425 2426 if (ProcessArgumentList) {2427 ProcessArgumentList = false;2428 // Create formal parameters.2429 LazyRandomTypeCollection &Types = types();2430 CVType CVArguments = Types.getType(Proc.getArgumentList());2431 if (Error Err = finishVisitation(CVArguments, Proc.getArgumentList(),2432 FunctionDcl))2433 return Err;2434 }2435 }2436 2437 return Error::success();2438}2439 2440// LF_UNION (TPI)2441Error LVLogicalVisitor::visitKnownRecord(CVType &Record, UnionRecord &Union,2442 TypeIndex TI, LVElement *Element) {2443 LLVM_DEBUG({2444 printTypeBegin(Record, TI, Element, StreamTPI);2445 W.printNumber("MemberCount", Union.getMemberCount());2446 printTypeIndex("FieldList", Union.getFieldList(), StreamTPI);2447 W.printNumber("SizeOf", Union.getSize());2448 W.printString("Name", Union.getName());2449 if (Union.hasUniqueName())2450 W.printString("UniqueName", Union.getUniqueName());2451 printTypeEnd(Record);2452 });2453 2454 LVScopeAggregate *Scope = static_cast<LVScopeAggregate *>(Element);2455 if (!Scope)2456 return Error::success();2457 2458 if (Scope->getIsFinalized())2459 return Error::success();2460 Scope->setIsFinalized();2461 2462 Scope->setName(Union.getName());2463 if (Union.hasUniqueName())2464 Scope->setLinkageName(Union.getUniqueName());2465 Scope->setBitSize(Union.getSize() * DWARF_CHAR_BIT);2466 2467 if (Union.isNested()) {2468 Scope->setIsNested();2469 createParents(Union.getName(), Scope);2470 } else {2471 if (LVScope *Namespace = Shared->NamespaceDeduction.get(Union.getName()))2472 Namespace->addElement(Scope);2473 else2474 Reader->getCompileUnit()->addElement(Scope);2475 }2476 2477 if (!Union.getFieldList().isNoneType()) {2478 LazyRandomTypeCollection &Types = types();2479 // Pass down the TypeIndex 'TI' for the aggregate containing the field list.2480 CVType CVFieldList = Types.getType(Union.getFieldList());2481 if (Error Err = finishVisitation(CVFieldList, TI, Scope))2482 return Err;2483 }2484 2485 return Error::success();2486}2487 2488// LF_TYPESERVER2 (TPI)2489Error LVLogicalVisitor::visitKnownRecord(CVType &Record, TypeServer2Record &TS,2490 TypeIndex TI, LVElement *Element) {2491 LLVM_DEBUG({2492 printTypeBegin(Record, TI, Element, StreamTPI);2493 W.printString("Guid", formatv("{0}", TS.getGuid()).str());2494 W.printNumber("Age", TS.getAge());2495 W.printString("Name", TS.getName());2496 printTypeEnd(Record);2497 });2498 return Error::success();2499}2500 2501// LF_VFTABLE (TPI)2502Error LVLogicalVisitor::visitKnownRecord(CVType &Record, VFTableRecord &VFT,2503 TypeIndex TI, LVElement *Element) {2504 LLVM_DEBUG({2505 printTypeBegin(Record, TI, Element, StreamTPI);2506 printTypeIndex("CompleteClass", VFT.getCompleteClass(), StreamTPI);2507 printTypeIndex("OverriddenVFTable", VFT.getOverriddenVTable(), StreamTPI);2508 W.printHex("VFPtrOffset", VFT.getVFPtrOffset());2509 W.printString("VFTableName", VFT.getName());2510 for (const StringRef &N : VFT.getMethodNames())2511 W.printString("MethodName", N);2512 printTypeEnd(Record);2513 });2514 return Error::success();2515}2516 2517// LF_VTSHAPE (TPI)2518Error LVLogicalVisitor::visitKnownRecord(CVType &Record,2519 VFTableShapeRecord &Shape,2520 TypeIndex TI, LVElement *Element) {2521 LLVM_DEBUG({2522 printTypeBegin(Record, TI, Element, StreamTPI);2523 W.printNumber("VFEntryCount", Shape.getEntryCount());2524 printTypeEnd(Record);2525 });2526 return Error::success();2527}2528 2529// LF_SUBSTR_LIST (TPI)/(IPI)2530Error LVLogicalVisitor::visitKnownRecord(CVType &Record,2531 StringListRecord &Strings,2532 TypeIndex TI, LVElement *Element) {2533 // All the indices are references into the TPI/IPI stream.2534 LLVM_DEBUG({2535 printTypeBegin(Record, TI, Element, StreamIPI);2536 ArrayRef<TypeIndex> Indices = Strings.getIndices();2537 uint32_t Size = Indices.size();2538 W.printNumber("NumStrings", Size);2539 ListScope Arguments(W, "Strings");2540 for (uint32_t I = 0; I < Size; ++I)2541 printTypeIndex("String", Indices[I], StreamIPI);2542 printTypeEnd(Record);2543 });2544 return Error::success();2545}2546 2547// LF_STRING_ID (TPI)/(IPI)2548Error LVLogicalVisitor::visitKnownRecord(CVType &Record, StringIdRecord &String,2549 TypeIndex TI, LVElement *Element) {2550 // All args are references into the TPI/IPI stream.2551 LLVM_DEBUG({2552 printTypeIndex("\nTI", TI, StreamIPI);2553 printTypeIndex("Id", String.getId(), StreamIPI);2554 W.printString("StringData", String.getString());2555 });2556 2557 if (LVScope *Namespace = Shared->NamespaceDeduction.get(2558 String.getString(), /*CheckScope=*/false)) {2559 // The function is already at different scope. In order to reflect2560 // the correct parent, move it to the namespace.2561 if (LVScope *Scope = Element->getParentScope())2562 Scope->removeElement(Element);2563 Namespace->addElement(Element);2564 }2565 2566 return Error::success();2567}2568 2569// LF_UDT_SRC_LINE (TPI)/(IPI)2570Error LVLogicalVisitor::visitKnownRecord(CVType &Record,2571 UdtSourceLineRecord &SourceLine,2572 TypeIndex TI, LVElement *Element) {2573 // All args are references into the TPI/IPI stream.2574 LLVM_DEBUG({2575 printTypeIndex("\nTI", TI, StreamIPI);2576 printTypeIndex("UDT", SourceLine.getUDT(), StreamIPI);2577 printTypeIndex("SourceFile", SourceLine.getSourceFile(), StreamIPI);2578 W.printNumber("LineNumber", SourceLine.getLineNumber());2579 });2580 return Error::success();2581}2582 2583// LF_UDT_MOD_SRC_LINE (TPI)/(IPI)2584Error LVLogicalVisitor::visitKnownRecord(CVType &Record,2585 UdtModSourceLineRecord &ModSourceLine,2586 TypeIndex TI, LVElement *Element) {2587 // All args are references into the TPI/IPI stream.2588 LLVM_DEBUG({2589 printTypeBegin(Record, TI, Element, StreamIPI);2590 printTypeIndex("\nTI", TI, StreamIPI);2591 printTypeIndex("UDT", ModSourceLine.getUDT(), StreamIPI);2592 printTypeIndex("SourceFile", ModSourceLine.getSourceFile(), StreamIPI);2593 W.printNumber("LineNumber", ModSourceLine.getLineNumber());2594 W.printNumber("Module", ModSourceLine.getModule());2595 printTypeEnd(Record);2596 });2597 return Error::success();2598}2599 2600// LF_PRECOMP (TPI)2601Error LVLogicalVisitor::visitKnownRecord(CVType &Record, PrecompRecord &Precomp,2602 TypeIndex TI, LVElement *Element) {2603 LLVM_DEBUG({2604 printTypeBegin(Record, TI, Element, StreamTPI);2605 W.printHex("StartIndex", Precomp.getStartTypeIndex());2606 W.printHex("Count", Precomp.getTypesCount());2607 W.printHex("Signature", Precomp.getSignature());2608 W.printString("PrecompFile", Precomp.getPrecompFilePath());2609 printTypeEnd(Record);2610 });2611 return Error::success();2612}2613 2614// LF_ENDPRECOMP (TPI)2615Error LVLogicalVisitor::visitKnownRecord(CVType &Record,2616 EndPrecompRecord &EndPrecomp,2617 TypeIndex TI, LVElement *Element) {2618 LLVM_DEBUG({2619 printTypeBegin(Record, TI, Element, StreamTPI);2620 W.printHex("Signature", EndPrecomp.getSignature());2621 printTypeEnd(Record);2622 });2623 return Error::success();2624}2625 2626Error LVLogicalVisitor::visitUnknownMember(CVMemberRecord &Record,2627 TypeIndex TI) {2628 LLVM_DEBUG({ W.printHex("UnknownMember", unsigned(Record.Kind)); });2629 return Error::success();2630}2631 2632// LF_BCLASS, LF_BINTERFACE2633Error LVLogicalVisitor::visitKnownMember(CVMemberRecord &Record,2634 BaseClassRecord &Base, TypeIndex TI,2635 LVElement *Element) {2636 LLVM_DEBUG({2637 printMemberBegin(Record, TI, Element, StreamTPI);2638 printTypeIndex("BaseType", Base.getBaseType(), StreamTPI);2639 W.printHex("BaseOffset", Base.getBaseOffset());2640 printMemberEnd(Record);2641 });2642 2643 createElement(Record.Kind);2644 if (LVSymbol *Symbol = CurrentSymbol) {2645 LVElement *BaseClass = getElement(StreamTPI, Base.getBaseType());2646 Symbol->setName(BaseClass->getName());2647 Symbol->setType(BaseClass);2648 Symbol->setAccessibilityCode(Base.getAccess());2649 static_cast<LVScope *>(Element)->addElement(Symbol);2650 }2651 2652 return Error::success();2653}2654 2655// LF_MEMBER2656Error LVLogicalVisitor::visitKnownMember(CVMemberRecord &Record,2657 DataMemberRecord &Field, TypeIndex TI,2658 LVElement *Element) {2659 LLVM_DEBUG({2660 printMemberBegin(Record, TI, Element, StreamTPI);2661 printTypeIndex("Type", Field.getType(), StreamTPI);2662 W.printHex("FieldOffset", Field.getFieldOffset());2663 W.printString("Name", Field.getName());2664 printMemberEnd(Record);2665 });2666 2667 // Create the data member.2668 createDataMember(Record, static_cast<LVScope *>(Element), Field.getName(),2669 Field.getType(), Field.getAccess());2670 return Error::success();2671}2672 2673// LF_ENUMERATE2674Error LVLogicalVisitor::visitKnownMember(CVMemberRecord &Record,2675 EnumeratorRecord &Enum, TypeIndex TI,2676 LVElement *Element) {2677 LLVM_DEBUG({2678 printMemberBegin(Record, TI, Element, StreamTPI);2679 W.printNumber("EnumValue", Enum.getValue());2680 W.printString("Name", Enum.getName());2681 printMemberEnd(Record);2682 });2683 2684 createElement(Record.Kind);2685 if (LVType *Type = CurrentType) {2686 Type->setName(Enum.getName());2687 SmallString<16> Value;2688 Enum.getValue().toString(Value, 16, true, true);2689 Type->setValue(Value);2690 static_cast<LVScope *>(Element)->addElement(CurrentType);2691 }2692 2693 return Error::success();2694}2695 2696// LF_INDEX2697Error LVLogicalVisitor::visitKnownMember(CVMemberRecord &Record,2698 ListContinuationRecord &Cont,2699 TypeIndex TI, LVElement *Element) {2700 LLVM_DEBUG({2701 printMemberBegin(Record, TI, Element, StreamTPI);2702 printTypeIndex("ContinuationIndex", Cont.getContinuationIndex(), StreamTPI);2703 printMemberEnd(Record);2704 });2705 return Error::success();2706}2707 2708// LF_NESTTYPE2709Error LVLogicalVisitor::visitKnownMember(CVMemberRecord &Record,2710 NestedTypeRecord &Nested, TypeIndex TI,2711 LVElement *Element) {2712 LLVM_DEBUG({2713 printMemberBegin(Record, TI, Element, StreamTPI);2714 printTypeIndex("Type", Nested.getNestedType(), StreamTPI);2715 W.printString("Name", Nested.getName());2716 printMemberEnd(Record);2717 });2718 2719 if (LVElement *Typedef = createElement(SymbolKind::S_UDT)) {2720 Typedef->setName(Nested.getName());2721 LVElement *NestedType = getElement(StreamTPI, Nested.getNestedType());2722 Typedef->setType(NestedType);2723 LVScope *Scope = static_cast<LVScope *>(Element);2724 Scope->addElement(Typedef);2725 2726 if (NestedType && NestedType->getIsNested()) {2727 // 'Element' is an aggregate type that may contains this nested type2728 // definition. Used their scoped names, to decide on their relationship.2729 StringRef RecordName = getRecordName(types(), TI);2730 2731 StringRef NestedTypeName = NestedType->getName();2732 if (NestedTypeName.size() && RecordName.size()) {2733 StringRef OuterComponent;2734 std::tie(OuterComponent, std::ignore) =2735 getInnerComponent(NestedTypeName);2736 // We have an already created nested type. Add it to the current scope2737 // and update all its children if any.2738 if (OuterComponent.size() && OuterComponent == RecordName) {2739 if (!NestedType->getIsScopedAlready()) {2740 Scope->addElement(NestedType);2741 NestedType->setIsScopedAlready();2742 NestedType->updateLevel(Scope);2743 }2744 Typedef->resetIncludeInPrint();2745 }2746 }2747 }2748 }2749 2750 return Error::success();2751}2752 2753// LF_ONEMETHOD2754Error LVLogicalVisitor::visitKnownMember(CVMemberRecord &Record,2755 OneMethodRecord &Method, TypeIndex TI,2756 LVElement *Element) {2757 LLVM_DEBUG({2758 printMemberBegin(Record, TI, Element, StreamTPI);2759 printTypeIndex("Type", Method.getType(), StreamTPI);2760 // If virtual, then read the vftable offset.2761 if (Method.isIntroducingVirtual())2762 W.printHex("VFTableOffset", Method.getVFTableOffset());2763 W.printString("Name", Method.getName());2764 printMemberEnd(Record);2765 });2766 2767 // All the LF_ONEMETHOD objects share the same type description.2768 // We have to create a scope object for each one and get the required2769 // information from the LF_MFUNCTION object.2770 ProcessArgumentList = true;2771 if (LVElement *MemberFunction = createElement(TypeLeafKind::LF_ONEMETHOD)) {2772 MemberFunction->setIsFinalized();2773 static_cast<LVScope *>(Element)->addElement(MemberFunction);2774 2775 MemberFunction->setName(Method.getName());2776 MemberFunction->setAccessibilityCode(Method.getAccess());2777 2778 MethodKind Kind = Method.getMethodKind();2779 if (Kind == MethodKind::Static)2780 MemberFunction->setIsStatic();2781 MemberFunction->setVirtualityCode(Kind);2782 2783 MethodOptions Flags = Method.Attrs.getFlags();2784 if (MethodOptions::CompilerGenerated ==2785 (Flags & MethodOptions::CompilerGenerated))2786 MemberFunction->setIsArtificial();2787 2788 LazyRandomTypeCollection &Types = types();2789 CVType CVMethodType = Types.getType(Method.getType());2790 if (Error Err =2791 finishVisitation(CVMethodType, Method.getType(), MemberFunction))2792 return Err;2793 }2794 ProcessArgumentList = false;2795 2796 return Error::success();2797}2798 2799// LF_METHOD2800Error LVLogicalVisitor::visitKnownMember(CVMemberRecord &Record,2801 OverloadedMethodRecord &Method,2802 TypeIndex TI, LVElement *Element) {2803 LLVM_DEBUG({2804 printMemberBegin(Record, TI, Element, StreamTPI);2805 W.printHex("MethodCount", Method.getNumOverloads());2806 printTypeIndex("MethodListIndex", Method.getMethodList(), StreamTPI);2807 W.printString("Name", Method.getName());2808 printMemberEnd(Record);2809 });2810 2811 // Record the overloaded method name, which will be used during the2812 // traversal of the method list.2813 LazyRandomTypeCollection &Types = types();2814 OverloadedMethodName = Method.getName();2815 CVType CVMethods = Types.getType(Method.getMethodList());2816 if (Error Err = finishVisitation(CVMethods, Method.getMethodList(), Element))2817 return Err;2818 2819 return Error::success();2820}2821 2822// LF_STMEMBER2823Error LVLogicalVisitor::visitKnownMember(CVMemberRecord &Record,2824 StaticDataMemberRecord &Field,2825 TypeIndex TI, LVElement *Element) {2826 LLVM_DEBUG({2827 printMemberBegin(Record, TI, Element, StreamTPI);2828 printTypeIndex("Type", Field.getType(), StreamTPI);2829 W.printString("Name", Field.getName());2830 printMemberEnd(Record);2831 });2832 2833 // Create the data member.2834 createDataMember(Record, static_cast<LVScope *>(Element), Field.getName(),2835 Field.getType(), Field.getAccess());2836 return Error::success();2837}2838 2839// LF_VFUNCTAB2840Error LVLogicalVisitor::visitKnownMember(CVMemberRecord &Record,2841 VFPtrRecord &VFTable, TypeIndex TI,2842 LVElement *Element) {2843 LLVM_DEBUG({2844 printMemberBegin(Record, TI, Element, StreamTPI);2845 printTypeIndex("Type", VFTable.getType(), StreamTPI);2846 printMemberEnd(Record);2847 });2848 return Error::success();2849}2850 2851// LF_VBCLASS, LF_IVBCLASS2852Error LVLogicalVisitor::visitKnownMember(CVMemberRecord &Record,2853 VirtualBaseClassRecord &Base,2854 TypeIndex TI, LVElement *Element) {2855 LLVM_DEBUG({2856 printMemberBegin(Record, TI, Element, StreamTPI);2857 printTypeIndex("BaseType", Base.getBaseType(), StreamTPI);2858 printTypeIndex("VBPtrType", Base.getVBPtrType(), StreamTPI);2859 W.printHex("VBPtrOffset", Base.getVBPtrOffset());2860 W.printHex("VBTableIndex", Base.getVTableIndex());2861 printMemberEnd(Record);2862 });2863 2864 createElement(Record.Kind);2865 if (LVSymbol *Symbol = CurrentSymbol) {2866 LVElement *BaseClass = getElement(StreamTPI, Base.getBaseType());2867 Symbol->setName(BaseClass->getName());2868 Symbol->setType(BaseClass);2869 Symbol->setAccessibilityCode(Base.getAccess());2870 Symbol->setVirtualityCode(MethodKind::Virtual);2871 static_cast<LVScope *>(Element)->addElement(Symbol);2872 }2873 2874 return Error::success();2875}2876 2877Error LVLogicalVisitor::visitMemberRecord(CVMemberRecord &Record,2878 TypeVisitorCallbacks &Callbacks,2879 TypeIndex TI, LVElement *Element) {2880 if (Error Err = Callbacks.visitMemberBegin(Record))2881 return Err;2882 2883 switch (Record.Kind) {2884 default:2885 if (Error Err = Callbacks.visitUnknownMember(Record))2886 return Err;2887 break;2888#define MEMBER_RECORD(EnumName, EnumVal, Name) \2889 case EnumName: { \2890 if (Error Err = \2891 visitKnownMember<Name##Record>(Record, Callbacks, TI, Element)) \2892 return Err; \2893 break; \2894 }2895#define MEMBER_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName) \2896 MEMBER_RECORD(EnumVal, EnumVal, AliasName)2897#define TYPE_RECORD(EnumName, EnumVal, Name)2898#define TYPE_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName)2899#include "llvm/DebugInfo/CodeView/CodeViewTypes.def"2900 }2901 2902 if (Error Err = Callbacks.visitMemberEnd(Record))2903 return Err;2904 2905 return Error::success();2906}2907 2908Error LVLogicalVisitor::finishVisitation(CVType &Record, TypeIndex TI,2909 LVElement *Element) {2910 switch (Record.kind()) {2911 default:2912 if (Error Err = visitUnknownType(Record, TI))2913 return Err;2914 break;2915#define TYPE_RECORD(EnumName, EnumVal, Name) \2916 case EnumName: { \2917 if (Error Err = visitKnownRecord<Name##Record>(Record, TI, Element)) \2918 return Err; \2919 break; \2920 }2921#define TYPE_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName) \2922 TYPE_RECORD(EnumVal, EnumVal, AliasName)2923#define MEMBER_RECORD(EnumName, EnumVal, Name)2924#define MEMBER_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName)2925#include "llvm/DebugInfo/CodeView/CodeViewTypes.def"2926 }2927 2928 return Error::success();2929}2930 2931// Customized version of 'FieldListVisitHelper'.2932Error LVLogicalVisitor::visitFieldListMemberStream(2933 TypeIndex TI, LVElement *Element, ArrayRef<uint8_t> FieldList) {2934 BinaryByteStream Stream(FieldList, llvm::endianness::little);2935 BinaryStreamReader Reader(Stream);2936 FieldListDeserializer Deserializer(Reader);2937 TypeVisitorCallbackPipeline Pipeline;2938 Pipeline.addCallbackToPipeline(Deserializer);2939 2940 TypeLeafKind Leaf;2941 while (!Reader.empty()) {2942 if (Error Err = Reader.readEnum(Leaf))2943 return Err;2944 2945 CVMemberRecord Record;2946 Record.Kind = Leaf;2947 if (Error Err = visitMemberRecord(Record, Pipeline, TI, Element))2948 return Err;2949 }2950 2951 return Error::success();2952}2953 2954void LVLogicalVisitor::addElement(LVScope *Scope, bool IsCompileUnit) {2955 // The CodeView specifications does not treat S_COMPILE2 and S_COMPILE32956 // as symbols that open a scope. The CodeView reader, treat them in a2957 // similar way as DWARF. As there is no a symbole S_END to close the2958 // compile unit, we need to check for the next compile unit.2959 if (IsCompileUnit) {2960 if (!ScopeStack.empty())2961 popScope();2962 InCompileUnitScope = true;2963 }2964 2965 pushScope(Scope);2966 ReaderParent->addElement(Scope);2967}2968 2969void LVLogicalVisitor::addElement(LVSymbol *Symbol) {2970 ReaderScope->addElement(Symbol);2971}2972 2973void LVLogicalVisitor::addElement(LVType *Type) {2974 ReaderScope->addElement(Type);2975}2976 2977LVElement *LVLogicalVisitor::createElement(TypeLeafKind Kind) {2978 CurrentScope = nullptr;2979 CurrentSymbol = nullptr;2980 CurrentType = nullptr;2981 2982 if (Kind < TypeIndex::FirstNonSimpleIndex) {2983 CurrentType = Reader->createType();2984 CurrentType->setIsBase();2985 CurrentType->setTag(dwarf::DW_TAG_base_type);2986 if (options().getAttributeBase())2987 CurrentType->setIncludeInPrint();2988 return CurrentType;2989 }2990 2991 switch (Kind) {2992 // Types.2993 case TypeLeafKind::LF_ENUMERATE:2994 CurrentType = Reader->createTypeEnumerator();2995 CurrentType->setTag(dwarf::DW_TAG_enumerator);2996 return CurrentType;2997 case TypeLeafKind::LF_MODIFIER:2998 CurrentType = Reader->createType();2999 CurrentType->setIsModifier();3000 return CurrentType;3001 case TypeLeafKind::LF_POINTER:3002 CurrentType = Reader->createType();3003 CurrentType->setIsPointer();3004 CurrentType->setName("*");3005 CurrentType->setTag(dwarf::DW_TAG_pointer_type);3006 return CurrentType;3007 3008 // Symbols.3009 case TypeLeafKind::LF_BCLASS:3010 case TypeLeafKind::LF_IVBCLASS:3011 case TypeLeafKind::LF_VBCLASS:3012 CurrentSymbol = Reader->createSymbol();3013 CurrentSymbol->setTag(dwarf::DW_TAG_inheritance);3014 CurrentSymbol->setIsInheritance();3015 return CurrentSymbol;3016 case TypeLeafKind::LF_MEMBER:3017 case TypeLeafKind::LF_STMEMBER:3018 CurrentSymbol = Reader->createSymbol();3019 CurrentSymbol->setIsMember();3020 CurrentSymbol->setTag(dwarf::DW_TAG_member);3021 return CurrentSymbol;3022 3023 // Scopes.3024 case TypeLeafKind::LF_ARRAY:3025 CurrentScope = Reader->createScopeArray();3026 CurrentScope->setTag(dwarf::DW_TAG_array_type);3027 return CurrentScope;3028 case TypeLeafKind::LF_CLASS:3029 CurrentScope = Reader->createScopeAggregate();3030 CurrentScope->setTag(dwarf::DW_TAG_class_type);3031 CurrentScope->setIsClass();3032 return CurrentScope;3033 case TypeLeafKind::LF_ENUM:3034 CurrentScope = Reader->createScopeEnumeration();3035 CurrentScope->setTag(dwarf::DW_TAG_enumeration_type);3036 return CurrentScope;3037 case TypeLeafKind::LF_METHOD:3038 case TypeLeafKind::LF_ONEMETHOD:3039 case TypeLeafKind::LF_PROCEDURE:3040 CurrentScope = Reader->createScopeFunction();3041 CurrentScope->setIsSubprogram();3042 CurrentScope->setTag(dwarf::DW_TAG_subprogram);3043 return CurrentScope;3044 case TypeLeafKind::LF_STRUCTURE:3045 CurrentScope = Reader->createScopeAggregate();3046 CurrentScope->setIsStructure();3047 CurrentScope->setTag(dwarf::DW_TAG_structure_type);3048 return CurrentScope;3049 case TypeLeafKind::LF_UNION:3050 CurrentScope = Reader->createScopeAggregate();3051 CurrentScope->setIsUnion();3052 CurrentScope->setTag(dwarf::DW_TAG_union_type);3053 return CurrentScope;3054 default:3055 // If '--internal=tag' and '--print=warning' are specified in the command3056 // line, we record and print each seen 'TypeLeafKind'.3057 break;3058 }3059 return nullptr;3060}3061 3062LVElement *LVLogicalVisitor::createElement(SymbolKind Kind) {3063 CurrentScope = nullptr;3064 CurrentSymbol = nullptr;3065 CurrentType = nullptr;3066 switch (Kind) {3067 // Types.3068 case SymbolKind::S_UDT:3069 CurrentType = Reader->createTypeDefinition();3070 CurrentType->setTag(dwarf::DW_TAG_typedef);3071 return CurrentType;3072 3073 // Symbols.3074 case SymbolKind::S_CONSTANT:3075 CurrentSymbol = Reader->createSymbol();3076 CurrentSymbol->setIsConstant();3077 CurrentSymbol->setTag(dwarf::DW_TAG_constant);3078 return CurrentSymbol;3079 3080 case SymbolKind::S_BPREL32:3081 case SymbolKind::S_REGREL32:3082 case SymbolKind::S_GDATA32:3083 case SymbolKind::S_LDATA32:3084 case SymbolKind::S_LOCAL:3085 // During the symbol traversal more information is available to3086 // determine if the symbol is a parameter or a variable. At this3087 // stage mark it as variable.3088 CurrentSymbol = Reader->createSymbol();3089 CurrentSymbol->setIsVariable();3090 CurrentSymbol->setTag(dwarf::DW_TAG_variable);3091 return CurrentSymbol;3092 3093 // Scopes.3094 case SymbolKind::S_BLOCK32:3095 CurrentScope = Reader->createScope();3096 CurrentScope->setIsLexicalBlock();3097 CurrentScope->setTag(dwarf::DW_TAG_lexical_block);3098 return CurrentScope;3099 case SymbolKind::S_COMPILE2:3100 case SymbolKind::S_COMPILE3:3101 CurrentScope = Reader->createScopeCompileUnit();3102 CurrentScope->setTag(dwarf::DW_TAG_compile_unit);3103 Reader->setCompileUnit(static_cast<LVScopeCompileUnit *>(CurrentScope));3104 return CurrentScope;3105 case SymbolKind::S_INLINESITE:3106 case SymbolKind::S_INLINESITE2:3107 CurrentScope = Reader->createScopeFunctionInlined();3108 CurrentScope->setIsInlinedFunction();3109 CurrentScope->setTag(dwarf::DW_TAG_inlined_subroutine);3110 return CurrentScope;3111 case SymbolKind::S_LPROC32:3112 case SymbolKind::S_GPROC32:3113 case SymbolKind::S_LPROC32_ID:3114 case SymbolKind::S_GPROC32_ID:3115 case SymbolKind::S_SEPCODE:3116 case SymbolKind::S_THUNK32:3117 CurrentScope = Reader->createScopeFunction();3118 CurrentScope->setIsSubprogram();3119 CurrentScope->setTag(dwarf::DW_TAG_subprogram);3120 return CurrentScope;3121 default:3122 // If '--internal=tag' and '--print=warning' are specified in the command3123 // line, we record and print each seen 'SymbolKind'.3124 break;3125 }3126 return nullptr;3127}3128 3129LVElement *LVLogicalVisitor::createElement(TypeIndex TI, TypeLeafKind Kind) {3130 LVElement *Element = Shared->TypeRecords.find(StreamTPI, TI);3131 if (!Element) {3132 // We are dealing with a base type or pointer to a base type, which are3133 // not included explicitly in the CodeView format.3134 if (Kind < TypeIndex::FirstNonSimpleIndex) {3135 Element = createElement(Kind);3136 Element->setIsFinalized();3137 Shared->TypeRecords.add(StreamTPI, (TypeIndex)Kind, Kind, Element);3138 Element->setOffset(Kind);3139 return Element;3140 }3141 // We are dealing with a pointer to a base type.3142 if (TI.getIndex() < TypeIndex::FirstNonSimpleIndex) {3143 Element = createElement(Kind);3144 Shared->TypeRecords.add(StreamTPI, TI, Kind, Element);3145 Element->setOffset(TI.getIndex());3146 Element->setOffsetFromTypeIndex();3147 return Element;3148 }3149 3150 W.printString("** Not implemented. **");3151 printTypeIndex("TypeIndex", TI, StreamTPI);3152 W.printString("TypeLeafKind", formatTypeLeafKind(Kind));3153 return nullptr;3154 }3155 3156 Element->setOffset(TI.getIndex());3157 Element->setOffsetFromTypeIndex();3158 return Element;3159}3160 3161void LVLogicalVisitor::createDataMember(CVMemberRecord &Record, LVScope *Parent,3162 StringRef Name, TypeIndex TI,3163 MemberAccess Access) {3164 LLVM_DEBUG({3165 printTypeIndex("TypeIndex", TI, StreamTPI);3166 W.printString("TypeName", Name);3167 });3168 3169 createElement(Record.Kind);3170 if (LVSymbol *Symbol = CurrentSymbol) {3171 Symbol->setName(Name);3172 if (TI.isNoneType() || TI.isSimple())3173 Symbol->setType(getElement(StreamTPI, TI));3174 else {3175 LazyRandomTypeCollection &Types = types();3176 CVType CVMemberType = Types.getType(TI);3177 if (CVMemberType.kind() == LF_BITFIELD) {3178 if (Error Err = finishVisitation(CVMemberType, TI, Symbol)) {3179 consumeError(std::move(Err));3180 return;3181 }3182 } else3183 Symbol->setType(getElement(StreamTPI, TI));3184 }3185 Symbol->setAccessibilityCode(Access);3186 Parent->addElement(Symbol);3187 }3188}3189 3190LVSymbol *LVLogicalVisitor::createParameter(LVElement *Element, StringRef Name,3191 LVScope *Parent) {3192 LVSymbol *Parameter = Reader->createSymbol();3193 Parent->addElement(Parameter);3194 Parameter->setIsParameter();3195 Parameter->setTag(dwarf::DW_TAG_formal_parameter);3196 Parameter->setName(Name);3197 Parameter->setType(Element);3198 return Parameter;3199}3200 3201LVSymbol *LVLogicalVisitor::createParameter(TypeIndex TI, StringRef Name,3202 LVScope *Parent) {3203 return createParameter(getElement(StreamTPI, TI), Name, Parent);3204}3205 3206LVType *LVLogicalVisitor::createBaseType(TypeIndex TI, StringRef TypeName) {3207 TypeLeafKind SimpleKind = (TypeLeafKind)TI.getSimpleKind();3208 TypeIndex TIR = (TypeIndex)SimpleKind;3209 LLVM_DEBUG({3210 printTypeIndex("TypeIndex", TIR, StreamTPI);3211 W.printString("TypeName", TypeName);3212 });3213 3214 if (LVElement *Element = Shared->TypeRecords.find(StreamTPI, TIR))3215 return static_cast<LVType *>(Element);3216 3217 if (createElement(TIR, SimpleKind)) {3218 CurrentType->setName(TypeName);3219 CurrentType->setBitSize(getSizeInBytesForTypeIndex(TIR) * DWARF_CHAR_BIT);3220 Reader->getCompileUnit()->addElement(CurrentType);3221 }3222 return CurrentType;3223}3224 3225LVType *LVLogicalVisitor::createPointerType(TypeIndex TI, StringRef TypeName) {3226 LLVM_DEBUG({3227 printTypeIndex("TypeIndex", TI, StreamTPI);3228 W.printString("TypeName", TypeName);3229 });3230 3231 if (LVElement *Element = Shared->TypeRecords.find(StreamTPI, TI))3232 return static_cast<LVType *>(Element);3233 3234 LVType *Pointee = createBaseType(TI, TypeName.drop_back(1));3235 if (createElement(TI, TypeLeafKind::LF_POINTER)) {3236 CurrentType->setIsFinalized();3237 CurrentType->setType(Pointee);3238 Reader->getCompileUnit()->addElement(CurrentType);3239 }3240 return CurrentType;3241}3242 3243void LVLogicalVisitor::createParents(StringRef ScopedName, LVElement *Element) {3244 // For the given test case:3245 //3246 // struct S { enum E { ... }; };3247 // S::E V;3248 //3249 // 0 | S_LOCAL `V`3250 // type=0x1004 (S::E), flags = none3251 // 0x1004 | LF_ENUM `S::E`3252 // options: has unique name | is nested3253 // 0x1009 | LF_STRUCTURE `S`3254 // options: contains nested class3255 //3256 // When the local 'V' is processed, its type 'E' is created. But There is3257 // no direct reference to its parent 'S'. We use the scoped name for 'E',3258 // to create its parents.3259 3260 // The input scoped name must have at least parent and nested names.3261 // Drop the last element name, as it corresponds to the nested type.3262 LVStringRefs Components = getAllLexicalComponents(ScopedName);3263 if (Components.size() < 2)3264 return;3265 Components.pop_back();3266 3267 LVStringRefs::size_type FirstNamespace;3268 LVStringRefs::size_type FirstAggregate;3269 std::tie(FirstNamespace, FirstAggregate) =3270 Shared->NamespaceDeduction.find(Components);3271 3272 LLVM_DEBUG({3273 W.printString("First Namespace", Components[FirstNamespace]);3274 W.printString("First NonNamespace", Components[FirstAggregate]);3275 });3276 3277 // Create any referenced namespaces.3278 if (FirstNamespace < FirstAggregate) {3279 Shared->NamespaceDeduction.get(3280 LVStringRefs(Components.begin() + FirstNamespace,3281 Components.begin() + FirstAggregate));3282 }3283 3284 // Traverse the enclosing scopes (aggregates) and create them. In the3285 // case of nested empty aggregates, MSVC does not emit a full record3286 // description. It emits only the reference record.3287 LVScope *Aggregate = nullptr;3288 TypeIndex TIAggregate;3289 std::string AggregateName = getScopedName(3290 LVStringRefs(Components.begin(), Components.begin() + FirstAggregate));3291 3292 // This traversal is executed at least once.3293 for (LVStringRefs::size_type Index = FirstAggregate;3294 Index < Components.size(); ++Index) {3295 AggregateName = getScopedName(LVStringRefs(Components.begin() + Index,3296 Components.begin() + Index + 1),3297 AggregateName);3298 TIAggregate = Shared->ForwardReferences.remap(3299 Shared->TypeRecords.find(StreamTPI, AggregateName));3300 Aggregate =3301 TIAggregate.isNoneType()3302 ? nullptr3303 : static_cast<LVScope *>(getElement(StreamTPI, TIAggregate));3304 }3305 3306 // Workaround for cases where LF_NESTTYPE is missing for nested templates.3307 // If we manage to get parent information from the scoped name, we can add3308 // the nested type without relying on the LF_NESTTYPE.3309 if (Aggregate && !Element->getIsScopedAlready()) {3310 Aggregate->addElement(Element);3311 Element->setIsScopedAlready();3312 }3313}3314 3315LVElement *LVLogicalVisitor::getElement(uint32_t StreamIdx, TypeIndex TI,3316 LVScope *Parent) {3317 LLVM_DEBUG({ printTypeIndex("TypeIndex", TI, StreamTPI); });3318 TI = Shared->ForwardReferences.remap(TI);3319 LLVM_DEBUG({ printTypeIndex("TypeIndex Remap", TI, StreamTPI); });3320 3321 LVElement *Element = Shared->TypeRecords.find(StreamIdx, TI);3322 if (!Element) {3323 if (TI.isNoneType() || TI.isSimple()) {3324 StringRef TypeName = TypeIndex::simpleTypeName(TI);3325 // If the name ends with "*", create 2 logical types: a pointer and a3326 // pointee type. TypeIndex is composed of a SympleTypeMode byte followed3327 // by a SimpleTypeKind byte. The logical pointer will be identified by3328 // the full TypeIndex value and the pointee by the SimpleTypeKind.3329 return (TypeName.back() == '*') ? createPointerType(TI, TypeName)3330 : createBaseType(TI, TypeName);3331 }3332 3333 LLVM_DEBUG({ W.printHex("TypeIndex not implemented: ", TI.getIndex()); });3334 return nullptr;3335 }3336 3337 // The element has been finalized.3338 if (Element->getIsFinalized())3339 return Element;3340 3341 // Add the element in case of a given parent.3342 if (Parent)3343 Parent->addElement(Element);3344 3345 // Check for a composite type.3346 LazyRandomTypeCollection &Types = types();3347 CVType CVRecord = Types.getType(TI);3348 if (Error Err = finishVisitation(CVRecord, TI, Element)) {3349 consumeError(std::move(Err));3350 return nullptr;3351 }3352 Element->setIsFinalized();3353 return Element;3354}3355 3356void LVLogicalVisitor::processLines() {3357 // Traverse the collected LF_UDT_SRC_LINE records and add the source line3358 // information to the logical elements.3359 for (const TypeIndex &Entry : Shared->LineRecords) {3360 CVType CVRecord = ids().getType(Entry);3361 UdtSourceLineRecord Line;3362 if (Error Err = TypeDeserializer::deserializeAs(3363 const_cast<CVType &>(CVRecord), Line))3364 consumeError(std::move(Err));3365 else {3366 LLVM_DEBUG({3367 printTypeIndex("UDT", Line.getUDT(), StreamIPI);3368 printTypeIndex("SourceFile", Line.getSourceFile(), StreamIPI);3369 W.printNumber("LineNumber", Line.getLineNumber());3370 });3371 3372 // The TypeIndex returned by 'getUDT()' must point to an already3373 // created logical element. If no logical element is found, it means3374 // the LF_UDT_SRC_LINE is associated with a system TypeIndex.3375 if (LVElement *Element = Shared->TypeRecords.find(3376 StreamTPI, Line.getUDT(), /*Create=*/false)) {3377 Element->setLineNumber(Line.getLineNumber());3378 Element->setFilenameIndex(3379 Shared->StringRecords.findIndex(Line.getSourceFile()));3380 }3381 }3382 }3383}3384 3385void LVLogicalVisitor::processNamespaces() {3386 // Create namespaces.3387 Shared->NamespaceDeduction.init();3388}3389 3390void LVLogicalVisitor::processFiles() { Shared->StringRecords.addFilenames(); }3391 3392void LVLogicalVisitor::printRecords(raw_ostream &OS) const {3393 if (!options().getInternalTag())3394 return;3395 3396 unsigned Count = 0;3397 auto PrintItem = [&](StringRef Name) {3398 auto NewLine = [&]() {3399 if (++Count == 4) {3400 Count = 0;3401 OS << "\n";3402 }3403 };3404 OS << format("%20s", Name.str().c_str());3405 NewLine();3406 };3407 3408 OS << "\nTypes:\n";3409 for (const TypeLeafKind &Kind : Shared->TypeKinds)3410 PrintItem(formatTypeLeafKind(Kind));3411 Shared->TypeKinds.clear();3412 3413 Count = 0;3414 OS << "\nSymbols:\n";3415 for (const SymbolKind &Kind : Shared->SymbolKinds)3416 PrintItem(LVCodeViewReader::getSymbolKindName(Kind));3417 Shared->SymbolKinds.clear();3418 3419 OS << "\n";3420}3421 3422Error LVLogicalVisitor::inlineSiteAnnotation(LVScope *AbstractFunction,3423 LVScope *InlinedFunction,3424 InlineSiteSym &InlineSite) {3425 // Get the parent scope to update the address ranges of the nested3426 // scope representing the inlined function.3427 LVAddress ParentLowPC = 0;3428 LVScope *Parent = InlinedFunction->getParentScope();3429 if (const LVLocations *Locations = Parent->getRanges()) {3430 if (!Locations->empty())3431 ParentLowPC = (*Locations->begin())->getLowerAddress();3432 }3433 3434 // For the given inlinesite, get the initial line number and its3435 // source filename. Update the logical scope representing it.3436 uint32_t LineNumber = 0;3437 StringRef Filename;3438 LVInlineeInfo::iterator Iter = InlineeInfo.find(InlineSite.Inlinee);3439 if (Iter != InlineeInfo.end()) {3440 LineNumber = Iter->second.first;3441 Filename = Iter->second.second;3442 AbstractFunction->setLineNumber(LineNumber);3443 // TODO: This part needs additional work in order to set properly the3444 // correct filename in order to detect changes between filenames.3445 // AbstractFunction->setFilename(Filename);3446 }3447 3448 LLVM_DEBUG({3449 dbgs() << "inlineSiteAnnotation\n"3450 << "Abstract: " << AbstractFunction->getName() << "\n"3451 << "Inlined: " << InlinedFunction->getName() << "\n"3452 << "Parent: " << Parent->getName() << "\n"3453 << "Low PC: " << hexValue(ParentLowPC) << "\n";3454 });3455 3456 // Get the source lines if requested by command line option.3457 if (!options().getPrintLines())3458 return Error::success();3459 3460 // Limitation: Currently we don't track changes in the FileOffset. The3461 // side effects are the caller that it is unable to differentiate the3462 // source filename for the inlined code.3463 uint64_t CodeOffset = ParentLowPC;3464 int32_t LineOffset = LineNumber;3465 uint32_t FileOffset = 0;3466 3467 auto UpdateClose = [&]() { LLVM_DEBUG({ dbgs() << ("\n"); }); };3468 auto UpdateCodeOffset = [&](uint32_t Delta) {3469 CodeOffset += Delta;3470 LLVM_DEBUG({3471 dbgs() << formatv(" code 0x{0} (+0x{1})", utohexstr(CodeOffset),3472 utohexstr(Delta));3473 });3474 };3475 auto UpdateLineOffset = [&](int32_t Delta) {3476 LineOffset += Delta;3477 LLVM_DEBUG({3478 char Sign = Delta > 0 ? '+' : '-';3479 dbgs() << formatv(" line {0} ({1}{2})", LineOffset, Sign,3480 std::abs(Delta));3481 });3482 };3483 auto UpdateFileOffset = [&](int32_t Offset) {3484 FileOffset = Offset;3485 LLVM_DEBUG({ dbgs() << formatv(" file {0}", FileOffset); });3486 };3487 3488 LVLines InlineeLines;3489 auto CreateLine = [&]() {3490 // Create the logical line record.3491 LVLineDebug *Line = Reader->createLineDebug();3492 Line->setAddress(CodeOffset);3493 Line->setLineNumber(LineOffset);3494 // TODO: This part needs additional work in order to set properly the3495 // correct filename in order to detect changes between filenames.3496 // Line->setFilename(Filename);3497 InlineeLines.push_back(Line);3498 };3499 3500 bool SeenLowAddress = false;3501 bool SeenHighAddress = false;3502 uint64_t LowPC = 0;3503 uint64_t HighPC = 0;3504 3505 for (auto &Annot : InlineSite.annotations()) {3506 LLVM_DEBUG({3507 dbgs() << formatv(" {0}",3508 fmt_align(toHex(Annot.Bytes), AlignStyle::Left, 9));3509 });3510 3511 // Use the opcode to interpret the integer values.3512 switch (Annot.OpCode) {3513 case BinaryAnnotationsOpCode::ChangeCodeOffset:3514 case BinaryAnnotationsOpCode::CodeOffset:3515 case BinaryAnnotationsOpCode::ChangeCodeLength:3516 UpdateCodeOffset(Annot.U1);3517 UpdateClose();3518 if (Annot.OpCode == BinaryAnnotationsOpCode::ChangeCodeOffset) {3519 CreateLine();3520 LowPC = CodeOffset;3521 SeenLowAddress = true;3522 break;3523 }3524 if (Annot.OpCode == BinaryAnnotationsOpCode::ChangeCodeLength) {3525 HighPC = CodeOffset - 1;3526 SeenHighAddress = true;3527 }3528 break;3529 case BinaryAnnotationsOpCode::ChangeCodeLengthAndCodeOffset:3530 UpdateCodeOffset(Annot.U2);3531 UpdateClose();3532 break;3533 case BinaryAnnotationsOpCode::ChangeLineOffset:3534 case BinaryAnnotationsOpCode::ChangeCodeOffsetAndLineOffset:3535 UpdateCodeOffset(Annot.U1);3536 UpdateLineOffset(Annot.S1);3537 UpdateClose();3538 if (Annot.OpCode ==3539 BinaryAnnotationsOpCode::ChangeCodeOffsetAndLineOffset)3540 CreateLine();3541 break;3542 case BinaryAnnotationsOpCode::ChangeFile:3543 UpdateFileOffset(Annot.U1);3544 UpdateClose();3545 break;3546 default:3547 break;3548 }3549 if (SeenLowAddress && SeenHighAddress) {3550 SeenLowAddress = false;3551 SeenHighAddress = false;3552 InlinedFunction->addObject(LowPC, HighPC);3553 }3554 }3555 3556 Reader->addInlineeLines(InlinedFunction, InlineeLines);3557 UpdateClose();3558 3559 return Error::success();3560}3561