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