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