LLVM 17.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 Components.erase(std::remove_if(Components.begin(), Components.end(),
469 [&](StringRef Component) {
470 LookupSet::iterator Iter =
471 IdentifiedNamespaces.find(Component);
472 return Iter == IdentifiedNamespaces.end();
473 }),
474 Components.end());
475
477 { dbgs() << formatv("ScopedName: '{0}'\n", ScopedName.str().c_str()); });
478
479 return get(Components);
480}
481
482#undef DEBUG_TYPE
483#define DEBUG_TYPE "CodeViewTypeVisitor"
484
485//===----------------------------------------------------------------------===//
486// TypeRecord traversal.
487//===----------------------------------------------------------------------===//
488void LVTypeVisitor::printTypeIndex(StringRef FieldName, TypeIndex TI,
489 uint32_t StreamIdx) const {
490 codeview::printTypeIndex(W, FieldName, TI,
491 StreamIdx == StreamTPI ? Types : Ids);
492}
493
496}
497
499 LLVM_DEBUG({
500 W.getOStream() << formatTypeLeafKind(Record.kind());
501 W.getOStream() << " (" << HexNumber(TI.getIndex()) << ")\n";
502 });
503
504 if (options().getInternalTag())
505 Shared->TypeKinds.insert(Record.kind());
506
507 // The collected type records, will be use to create the logical elements
508 // during the symbols traversal when a type is referenced.
509 CurrentTypeIndex = TI;
510 Shared->TypeRecords.add(StreamIdx, TI, Record.kind());
511 return Error::success();
512}
513
515 LLVM_DEBUG({ W.printNumber("Length", uint32_t(Record.content().size())); });
516 return Error::success();
517}
518
520 LLVM_DEBUG({
522 W.getOStream() << " {\n";
523 W.indent();
524 });
525 return Error::success();
526}
527
529 LLVM_DEBUG({
530 W.unindent();
531 W.startLine() << "}\n";
532 });
533 return Error::success();
534}
535
537 LLVM_DEBUG({ W.printHex("UnknownMember", unsigned(Record.Kind)); });
538 return Error::success();
539}
540
541// LF_BUILDINFO (TPI)/(IPI)
543 // All the args are references into the TPI/IPI stream.
544 LLVM_DEBUG({
545 W.printNumber("NumArgs", static_cast<uint32_t>(Args.getArgs().size()));
546 ListScope Arguments(W, "Arguments");
547 for (TypeIndex Arg : Args.getArgs())
548 printTypeIndex("ArgType", Arg, StreamIPI);
549 });
550
551 // Only add the strings that hold information about filenames. They will be
552 // used to complete the line/file information for the logical elements.
553 // There are other strings holding information about namespaces.
554 TypeIndex TI;
556
557 // Absolute CWD path
558 TI = Args.getArgs()[BuildInfoRecord::BuildInfoArg::CurrentDirectory];
559 String = Ids.getTypeName(TI);
560 if (!String.empty())
561 Shared->StringRecords.add(TI, String);
562
563 // Get the compile unit name.
564 TI = Args.getArgs()[BuildInfoRecord::BuildInfoArg::SourceFile];
565 String = Ids.getTypeName(TI);
566 if (!String.empty())
567 Shared->StringRecords.add(TI, String);
568 LogicalVisitor->setCompileUnitName(std::string(String));
569
570 return Error::success();
571}
572
573// LF_CLASS, LF_STRUCTURE, LF_INTERFACE (TPI)
575 LLVM_DEBUG({
576 printTypeIndex("TypeIndex", CurrentTypeIndex, StreamTPI);
577 printTypeIndex("FieldListType", Class.getFieldList(), StreamTPI);
578 W.printString("Name", Class.getName());
579 });
580
581 // Collect class name for scope deduction.
582 Shared->NamespaceDeduction.add(Class.getName());
583 Shared->ForwardReferences.record(Class.isForwardRef(), Class.getName(),
584 CurrentTypeIndex);
585
586 // Collect class name for contained scopes deduction.
587 Shared->TypeRecords.add(StreamIdx, CurrentTypeIndex, Class.getName());
588 return Error::success();
589}
590
591// LF_ENUM (TPI)
593 LLVM_DEBUG({
594 printTypeIndex("TypeIndex", CurrentTypeIndex, StreamTPI);
595 printTypeIndex("FieldListType", Enum.getFieldList(), StreamTPI);
596 W.printString("Name", Enum.getName());
597 });
598
599 // Collect enum name for scope deduction.
600 Shared->NamespaceDeduction.add(Enum.getName());
601 return Error::success();
602}
603
604// LF_FUNC_ID (TPI)/(IPI)
606 LLVM_DEBUG({
607 printTypeIndex("TypeIndex", CurrentTypeIndex, StreamTPI);
608 printTypeIndex("Type", Func.getFunctionType(), StreamTPI);
609 printTypeIndex("Parent", Func.getParentScope(), StreamTPI);
610 W.printString("Name", Func.getName());
611 });
612
613 // Collect function name for scope deduction.
614 Shared->NamespaceDeduction.add(Func.getName());
615 return Error::success();
616}
617
618// LF_PROCEDURE (TPI)
620 LLVM_DEBUG({
621 printTypeIndex("TypeIndex", CurrentTypeIndex, StreamTPI);
622 printTypeIndex("ReturnType", Proc.getReturnType(), StreamTPI);
623 W.printNumber("NumParameters", Proc.getParameterCount());
624 printTypeIndex("ArgListType", Proc.getArgumentList(), StreamTPI);
625 });
626
627 // Collect procedure information as they can be referenced by typedefs.
628 Shared->TypeRecords.add(StreamTPI, CurrentTypeIndex, {});
629 return Error::success();
630}
631
632// LF_STRING_ID (TPI)/(IPI)
634 // No additional references are needed.
635 LLVM_DEBUG({
636 printTypeIndex("Id", String.getId(), StreamIPI);
637 W.printString("StringData", String.getString());
638 });
639 return Error::success();
640}
641
642// LF_UDT_SRC_LINE (TPI)/(IPI)
645 // UDT and SourceFile are references into the TPI/IPI stream.
646 LLVM_DEBUG({
647 printTypeIndex("UDT", Line.getUDT(), StreamIPI);
648 printTypeIndex("SourceFile", Line.getSourceFile(), StreamIPI);
649 W.printNumber("LineNumber", Line.getLineNumber());
650 });
651
652 Shared->LineRecords.push_back(CurrentTypeIndex);
653 return Error::success();
654}
655
656// LF_UNION (TPI)
658 LLVM_DEBUG({
659 W.printNumber("MemberCount", Union.getMemberCount());
660 printTypeIndex("FieldList", Union.getFieldList(), StreamTPI);
661 W.printNumber("SizeOf", Union.getSize());
662 W.printString("Name", Union.getName());
663 if (Union.hasUniqueName())
664 W.printString("UniqueName", Union.getUniqueName());
665 });
666
667 // Collect union name for scope deduction.
668 Shared->NamespaceDeduction.add(Union.getName());
669 Shared->ForwardReferences.record(Union.isForwardRef(), Union.getName(),
670 CurrentTypeIndex);
671
672 // Collect class name for contained scopes deduction.
673 Shared->TypeRecords.add(StreamIdx, CurrentTypeIndex, Union.getName());
674 return Error::success();
675}
676
677#undef DEBUG_TYPE
678#define DEBUG_TYPE "CodeViewSymbolVisitor"
679
680//===----------------------------------------------------------------------===//
681// SymbolRecord traversal.
682//===----------------------------------------------------------------------===//
684 uint32_t RelocOffset,
686 StringRef *RelocSym) {
687 Reader->printRelocatedField(Label, CoffSection, RelocOffset, Offset,
688 RelocSym);
689}
690
693 StringRef *RelocSym) {
694 Reader->getLinkageName(CoffSection, RelocOffset, Offset, RelocSym);
695}
696
699 Expected<StringRef> Name = Reader->getFileNameForFileOffset(FileOffset);
700 if (!Name) {
701 consumeError(Name.takeError());
702 return {};
703 }
704 return *Name;
705}
706
708 return Reader->CVStringTable;
709}
710
711void LVSymbolVisitor::printLocalVariableAddrRange(
712 const LocalVariableAddrRange &Range, uint32_t RelocationOffset) {
713 DictScope S(W, "LocalVariableAddrRange");
714 if (ObjDelegate)
715 ObjDelegate->printRelocatedField("OffsetStart", RelocationOffset,
716 Range.OffsetStart);
717 W.printHex("ISectStart", Range.ISectStart);
718 W.printHex("Range", Range.Range);
719}
720
721void LVSymbolVisitor::printLocalVariableAddrGap(
723 for (const LocalVariableAddrGap &Gap : Gaps) {
724 ListScope S(W, "LocalVariableAddrGap");
725 W.printHex("GapStartOffset", Gap.GapStartOffset);
726 W.printHex("Range", Gap.Range);
727 }
728}
729
730void LVSymbolVisitor::printTypeIndex(StringRef FieldName, TypeIndex TI) const {
731 codeview::printTypeIndex(W, FieldName, TI, Types);
732}
733
735 return visitSymbolBegin(Record, 0);
736}
737
739 SymbolKind Kind = Record.kind();
740 LLVM_DEBUG({
741 W.printNumber("Offset", Offset);
742 W.printEnum("Begin Kind", unsigned(Kind), getSymbolTypeNames());
743 });
744
745 if (options().getInternalTag())
746 Shared->SymbolKinds.insert(Kind);
747
748 LogicalVisitor->CurrentElement = LogicalVisitor->createElement(Kind);
749 if (!LogicalVisitor->CurrentElement) {
750 LLVM_DEBUG({
751 // We have an unsupported Symbol or Type Record.
752 // W.printEnum("Kind ignored", unsigned(Kind), getSymbolTypeNames());
753 });
754 return Error::success();
755 }
756
757 // Offset carried by the traversal routines when dealing with streams.
758 CurrentOffset = Offset;
759 IsCompileUnit = false;
760 if (!LogicalVisitor->CurrentElement->getOffsetFromTypeIndex())
761 LogicalVisitor->CurrentElement->setOffset(Offset);
762 if (symbolOpensScope(Kind) || (IsCompileUnit = symbolIsCompileUnit(Kind))) {
763 assert(LogicalVisitor->CurrentScope && "Invalid scope!");
764 LogicalVisitor->addElement(LogicalVisitor->CurrentScope, IsCompileUnit);
765 } else {
766 if (LogicalVisitor->CurrentSymbol)
767 LogicalVisitor->addElement(LogicalVisitor->CurrentSymbol);
768 if (LogicalVisitor->CurrentType)
769 LogicalVisitor->addElement(LogicalVisitor->CurrentType);
770 }
771
772 return Error::success();
773}
774
776 SymbolKind Kind = Record.kind();
778 { W.printEnum("End Kind", unsigned(Kind), getSymbolTypeNames()); });
779
780 if (symbolEndsScope(Kind)) {
781 LogicalVisitor->popScope();
782 }
783
784 return Error::success();
785}
786
788 LLVM_DEBUG({ W.printNumber("Length", Record.length()); });
789 return Error::success();
790}
791
792// S_BLOCK32
794 LLVM_DEBUG({
795 W.printHex("CodeSize", Block.CodeSize);
796 W.printHex("Segment", Block.Segment);
797 W.printString("BlockName", Block.Name);
798 });
799
800 if (LVScope *Scope = LogicalVisitor->CurrentScope) {
802 if (ObjDelegate)
803 ObjDelegate->getLinkageName(Block.getRelocationOffset(), Block.CodeOffset,
804 &LinkageName);
805 Scope->setLinkageName(LinkageName);
806
807 if (options().getGeneralCollectRanges()) {
808 // Record converted segment::offset addressing for this scope.
809 LVAddress Addendum = Reader->getSymbolTableAddress(LinkageName);
810 LVAddress LowPC =
811 Reader->linearAddress(Block.Segment, Block.CodeOffset, Addendum);
812 LVAddress HighPC = LowPC + Block.CodeSize - 1;
813 Scope->addObject(LowPC, HighPC);
814 }
815 }
816
817 return Error::success();
818}
819
820// S_BPREL32
823 LLVM_DEBUG({
824 printTypeIndex("Type", Local.Type);
825 W.printNumber("Offset", Local.Offset);
826 W.printString("VarName", Local.Name);
827 });
828
829 if (LVSymbol *Symbol = LogicalVisitor->CurrentSymbol) {
830 Symbol->setName(Local.Name);
831 // From the MS_Symbol_Type.pdf documentation (S_BPREL32):
832 // This symbol specifies symbols that are allocated on the stack for a
833 // procedure. For C and C++, these include the actual function parameters
834 // and the local non-static variables of functions.
835 // However, the offset for 'this' comes as a negative value.
836
837 // Symbol was created as 'variable'; determine its real kind.
838 Symbol->resetIsVariable();
839
840 if (Local.Name.equals("this")) {
841 Symbol->setIsParameter();
842 Symbol->setIsArtificial();
843 } else {
844 // Determine symbol kind.
845 bool(Local.Offset > 0) ? Symbol->setIsParameter()
846 : Symbol->setIsVariable();
847 }
848
849 // Update correct debug information tag.
850 if (Symbol->getIsParameter())
851 Symbol->setTag(dwarf::DW_TAG_formal_parameter);
852
853 LVElement *Element = LogicalVisitor->getElement(StreamTPI, Local.Type);
854 if (Element && Element->getIsScoped()) {
855 // We have a local type. Find its parent function.
856 LVScope *Parent = Symbol->getFunctionParent();
857 // The element representing the type has been already finalized. If
858 // the type is an aggregate type, its members have been already added.
859 // As the type is local, its level will be changed.
860
861 // FIXME: Currently the algorithm used to scope lambda functions is
862 // incorrect. Before we allocate the type at this scope, check if is
863 // already allocated in other scope.
864 if (!Element->getParentScope()) {
865 Parent->addElement(Element);
866 Element->updateLevel(Parent);
867 }
868 }
869 Symbol->setType(Element);
870 }
871
872 return Error::success();
873}
874
875// S_REGREL32
878 LLVM_DEBUG({
879 printTypeIndex("Type", Local.Type);
880 W.printNumber("Offset", Local.Offset);
881 W.printString("VarName", Local.Name);
882 });
883
884 if (LVSymbol *Symbol = LogicalVisitor->CurrentSymbol) {
885 Symbol->setName(Local.Name);
886
887 // Symbol was created as 'variable'; determine its real kind.
888 Symbol->resetIsVariable();
889
890 // Check for the 'this' symbol.
891 if (Local.Name.equals("this")) {
892 Symbol->setIsArtificial();
893 Symbol->setIsParameter();
894 } else {
895 // Determine symbol kind.
896 determineSymbolKind(Symbol, Local.Register);
897 }
898
899 // Update correct debug information tag.
900 if (Symbol->getIsParameter())
901 Symbol->setTag(dwarf::DW_TAG_formal_parameter);
902
903 LVElement *Element = LogicalVisitor->getElement(StreamTPI, Local.Type);
904 if (Element && Element->getIsScoped()) {
905 // We have a local type. Find its parent function.
906 LVScope *Parent = Symbol->getFunctionParent();
907 // The element representing the type has been already finalized. If
908 // the type is an aggregate type, its members have been already added.
909 // As the type is local, its level will be changed.
910
911 // FIXME: Currently the algorithm used to scope lambda functions is
912 // incorrect. Before we allocate the type at this scope, check if is
913 // already allocated in other scope.
914 if (!Element->getParentScope()) {
915 Parent->addElement(Element);
916 Element->updateLevel(Parent);
917 }
918 }
919 Symbol->setType(Element);
920 }
921
922 return Error::success();
923}
924
925// S_BUILDINFO
927 BuildInfoSym &BuildInfo) {
928 LLVM_DEBUG({ printTypeIndex("BuildId", BuildInfo.BuildId); });
929
930 CVType CVBuildType = Ids.getType(BuildInfo.BuildId);
931 if (Error Err = LogicalVisitor->finishVisitation(
932 CVBuildType, BuildInfo.BuildId, Reader->getCompileUnit()))
933 return Err;
934
935 return Error::success();
936}
937
938// S_COMPILE2
940 Compile2Sym &Compile2) {
941 LLVM_DEBUG({
942 W.printEnum("Language", uint8_t(Compile2.getLanguage()),
944 W.printFlags("Flags", uint32_t(Compile2.getFlags()),
946 W.printEnum("Machine", unsigned(Compile2.Machine), getCPUTypeNames());
947 W.printString("VersionName", Compile2.Version);
948 });
949
950 // MSVC generates the following sequence for a CodeView module:
951 // S_OBJNAME --> Set 'CurrentObjectName'.
952 // S_COMPILE2 --> Set the compile unit name using 'CurrentObjectName'.
953 // ...
954 // S_BUILDINFO --> Extract the source name.
955 //
956 // Clang generates the following sequence for a CodeView module:
957 // S_COMPILE2 --> Set the compile unit name to empty string.
958 // ...
959 // S_BUILDINFO --> Extract the source name.
960 //
961 // For both toolchains, update the compile unit name from S_BUILDINFO.
962 if (LVScope *Scope = LogicalVisitor->CurrentScope) {
963 // The name of the CU, was extracted from the 'BuildInfo' subsection.
964 Reader->setCompileUnitCPUType(Compile2.Machine);
965 Scope->setName(CurrentObjectName);
966 if (options().getAttributeProducer())
967 Scope->setProducer(Compile2.Version);
968 getReader().isSystemEntry(Scope, CurrentObjectName);
969
970 // The line records in CodeView are recorded per Module ID. Update
971 // the relationship between the current CU and the Module ID.
972 Reader->addModule(Scope);
973
974 // Updated the collected strings with their associated compile unit.
975 Shared->StringRecords.addFilenames(Reader->getCompileUnit());
976 }
977
978 // Clear any previous ObjectName.
979 CurrentObjectName = "";
980 return Error::success();
981}
982
983// S_COMPILE3
985 Compile3Sym &Compile3) {
986 LLVM_DEBUG({
987 W.printEnum("Language", uint8_t(Compile3.getLanguage()),
989 W.printFlags("Flags", uint32_t(Compile3.getFlags()),
991 W.printEnum("Machine", unsigned(Compile3.Machine), getCPUTypeNames());
992 W.printString("VersionName", Compile3.Version);
993 });
994
995 // MSVC generates the following sequence for a CodeView module:
996 // S_OBJNAME --> Set 'CurrentObjectName'.
997 // S_COMPILE3 --> Set the compile unit name using 'CurrentObjectName'.
998 // ...
999 // S_BUILDINFO --> Extract the source name.
1000 //
1001 // Clang generates the following sequence for a CodeView module:
1002 // S_COMPILE3 --> Set the compile unit name to empty string.
1003 // ...
1004 // S_BUILDINFO --> Extract the source name.
1005 //
1006 // For both toolchains, update the compile unit name from S_BUILDINFO.
1007 if (LVScope *Scope = LogicalVisitor->CurrentScope) {
1008 // The name of the CU, was extracted from the 'BuildInfo' subsection.
1009 Reader->setCompileUnitCPUType(Compile3.Machine);
1010 Scope->setName(CurrentObjectName);
1011 if (options().getAttributeProducer())
1012 Scope->setProducer(Compile3.Version);
1013 getReader().isSystemEntry(Scope, CurrentObjectName);
1014
1015 // The line records in CodeView are recorded per Module ID. Update
1016 // the relationship between the current CU and the Module ID.
1017 Reader->addModule(Scope);
1018
1019 // Updated the collected strings with their associated compile unit.
1020 Shared->StringRecords.addFilenames(Reader->getCompileUnit());
1021 }
1022
1023 // Clear any previous ObjectName.
1024 CurrentObjectName = "";
1025 return Error::success();
1026}
1027
1028// S_CONSTANT, S_MANCONSTANT
1031 LLVM_DEBUG({
1032 printTypeIndex("Type", Constant.Type);
1033 W.printNumber("Value", Constant.Value);
1034 W.printString("Name", Constant.Name);
1035 });
1036
1037 if (LVSymbol *Symbol = LogicalVisitor->CurrentSymbol) {
1038 Symbol->setName(Constant.Name);
1039 Symbol->setType(LogicalVisitor->getElement(StreamTPI, Constant.Type));
1040 Symbol->resetIncludeInPrint();
1041 }
1042
1043 return Error::success();
1044}
1045
1046// S_DEFRANGE_FRAMEPOINTER_REL_FULL_SCOPE
1049 DefRangeFramePointerRelFullScopeSym &DefRangeFramePointerRelFullScope) {
1050 // DefRanges don't have types, just registers and code offsets.
1051 LLVM_DEBUG({
1052 if (LocalSymbol)
1053 W.getOStream() << formatv("Symbol: {0}, ", LocalSymbol->getName());
1054
1055 W.printNumber("Offset", DefRangeFramePointerRelFullScope.Offset);
1056 });
1057
1058 if (LVSymbol *Symbol = LocalSymbol) {
1059 Symbol->setHasCodeViewLocation();
1060 LocalSymbol = nullptr;
1061
1062 // Add location debug location. Operands: [Offset, 0].
1063 dwarf::Attribute Attr =
1064 dwarf::Attribute(SymbolKind::S_DEFRANGE_FRAMEPOINTER_REL_FULL_SCOPE);
1065
1066 uint64_t Operand1 = DefRangeFramePointerRelFullScope.Offset;
1067 Symbol->addLocation(Attr, 0, 0, 0, 0);
1068 Symbol->addLocationOperands(LVSmall(Attr), Operand1, /*Operand2=*/0);
1069 }
1070
1071 return Error::success();
1072}
1073
1074// S_DEFRANGE_FRAMEPOINTER_REL
1076 CVSymbol &Record, DefRangeFramePointerRelSym &DefRangeFramePointerRel) {
1077 // DefRanges don't have types, just registers and code offsets.
1078 LLVM_DEBUG({
1079 if (LocalSymbol)
1080 W.getOStream() << formatv("Symbol: {0}, ", LocalSymbol->getName());
1081
1082 W.printNumber("Offset", DefRangeFramePointerRel.Hdr.Offset);
1083 printLocalVariableAddrRange(DefRangeFramePointerRel.Range,
1084 DefRangeFramePointerRel.getRelocationOffset());
1085 printLocalVariableAddrGap(DefRangeFramePointerRel.Gaps);
1086 });
1087
1088 // We are expecting the following sequence:
1089 // 128 | S_LOCAL [size = 20] `ParamBar`
1090 // ...
1091 // 148 | S_DEFRANGE_FRAMEPOINTER_REL [size = 16]
1092 if (LVSymbol *Symbol = LocalSymbol) {
1093 Symbol->setHasCodeViewLocation();
1094 LocalSymbol = nullptr;
1095
1096 // Add location debug location. Operands: [Offset, 0].
1097 dwarf::Attribute Attr =
1098 dwarf::Attribute(SymbolKind::S_DEFRANGE_FRAMEPOINTER_REL);
1099 uint64_t Operand1 = DefRangeFramePointerRel.Hdr.Offset;
1100
1101 LocalVariableAddrRange Range = DefRangeFramePointerRel.Range;
1103 Reader->linearAddress(Range.ISectStart, Range.OffsetStart);
1104
1105 Symbol->addLocation(Attr, Address, Address + Range.Range, 0, 0);
1106 Symbol->addLocationOperands(LVSmall(Attr), Operand1, /*Operand2=*/0);
1107 }
1108
1109 return Error::success();
1110}
1111
1112// S_DEFRANGE_REGISTER_REL
1114 CVSymbol &Record, DefRangeRegisterRelSym &DefRangeRegisterRel) {
1115 // DefRanges don't have types, just registers and code offsets.
1116 LLVM_DEBUG({
1117 if (LocalSymbol)
1118 W.getOStream() << formatv("Symbol: {0}, ", LocalSymbol->getName());
1119
1120 W.printBoolean("HasSpilledUDTMember",
1121 DefRangeRegisterRel.hasSpilledUDTMember());
1122 W.printNumber("OffsetInParent", DefRangeRegisterRel.offsetInParent());
1123 W.printNumber("BasePointerOffset",
1124 DefRangeRegisterRel.Hdr.BasePointerOffset);
1125 printLocalVariableAddrRange(DefRangeRegisterRel.Range,
1126 DefRangeRegisterRel.getRelocationOffset());
1127 printLocalVariableAddrGap(DefRangeRegisterRel.Gaps);
1128 });
1129
1130 if (LVSymbol *Symbol = LocalSymbol) {
1131 Symbol->setHasCodeViewLocation();
1132 LocalSymbol = nullptr;
1133
1134 // Add location debug location. Operands: [Register, Offset].
1135 dwarf::Attribute Attr =
1136 dwarf::Attribute(SymbolKind::S_DEFRANGE_REGISTER_REL);
1137 uint64_t Operand1 = DefRangeRegisterRel.Hdr.Register;
1138 uint64_t Operand2 = DefRangeRegisterRel.Hdr.BasePointerOffset;
1139
1140 LocalVariableAddrRange Range = DefRangeRegisterRel.Range;
1142 Reader->linearAddress(Range.ISectStart, Range.OffsetStart);
1143
1144 Symbol->addLocation(Attr, Address, Address + Range.Range, 0, 0);
1145 Symbol->addLocationOperands(LVSmall(Attr), Operand1, Operand2);
1146 }
1147
1148 return Error::success();
1149}
1150
1151// S_DEFRANGE_REGISTER
1153 DefRangeRegisterSym &DefRangeRegister) {
1154 // DefRanges don't have types, just registers and code offsets.
1155 LLVM_DEBUG({
1156 if (LocalSymbol)
1157 W.getOStream() << formatv("Symbol: {0}, ", LocalSymbol->getName());
1158
1159 W.printEnum("Register", uint16_t(DefRangeRegister.Hdr.Register),
1161 W.printNumber("MayHaveNoName", DefRangeRegister.Hdr.MayHaveNoName);
1162 printLocalVariableAddrRange(DefRangeRegister.Range,
1163 DefRangeRegister.getRelocationOffset());
1164 printLocalVariableAddrGap(DefRangeRegister.Gaps);
1165 });
1166
1167 if (LVSymbol *Symbol = LocalSymbol) {
1168 Symbol->setHasCodeViewLocation();
1169 LocalSymbol = nullptr;
1170
1171 // Add location debug location. Operands: [Register, 0].
1172 dwarf::Attribute Attr = dwarf::Attribute(SymbolKind::S_DEFRANGE_REGISTER);
1173 uint64_t Operand1 = DefRangeRegister.Hdr.Register;
1174
1175 LocalVariableAddrRange Range = DefRangeRegister.Range;
1177 Reader->linearAddress(Range.ISectStart, Range.OffsetStart);
1178
1179 Symbol->addLocation(Attr, Address, Address + Range.Range, 0, 0);
1180 Symbol->addLocationOperands(LVSmall(Attr), Operand1, /*Operand2=*/0);
1181 }
1182
1183 return Error::success();
1184}
1185
1186// S_DEFRANGE_SUBFIELD_REGISTER
1188 CVSymbol &Record, DefRangeSubfieldRegisterSym &DefRangeSubfieldRegister) {
1189 // DefRanges don't have types, just registers and code offsets.
1190 LLVM_DEBUG({
1191 if (LocalSymbol)
1192 W.getOStream() << formatv("Symbol: {0}, ", LocalSymbol->getName());
1193
1194 W.printEnum("Register", uint16_t(DefRangeSubfieldRegister.Hdr.Register),
1196 W.printNumber("MayHaveNoName", DefRangeSubfieldRegister.Hdr.MayHaveNoName);
1197 W.printNumber("OffsetInParent",
1198 DefRangeSubfieldRegister.Hdr.OffsetInParent);
1199 printLocalVariableAddrRange(DefRangeSubfieldRegister.Range,
1200 DefRangeSubfieldRegister.getRelocationOffset());
1201 printLocalVariableAddrGap(DefRangeSubfieldRegister.Gaps);
1202 });
1203
1204 if (LVSymbol *Symbol = LocalSymbol) {
1205 Symbol->setHasCodeViewLocation();
1206 LocalSymbol = nullptr;
1207
1208 // Add location debug location. Operands: [Register, 0].
1209 dwarf::Attribute Attr =
1210 dwarf::Attribute(SymbolKind::S_DEFRANGE_SUBFIELD_REGISTER);
1211 uint64_t Operand1 = DefRangeSubfieldRegister.Hdr.Register;
1212
1213 LocalVariableAddrRange Range = DefRangeSubfieldRegister.Range;
1215 Reader->linearAddress(Range.ISectStart, Range.OffsetStart);
1216
1217 Symbol->addLocation(Attr, Address, Address + Range.Range, 0, 0);
1218 Symbol->addLocationOperands(LVSmall(Attr), Operand1, /*Operand2=*/0);
1219 }
1220
1221 return Error::success();
1222}
1223
1224// S_DEFRANGE_SUBFIELD
1226 DefRangeSubfieldSym &DefRangeSubfield) {
1227 // DefRanges don't have types, just registers and code offsets.
1228 LLVM_DEBUG({
1229 if (LocalSymbol)
1230 W.getOStream() << formatv("Symbol: {0}, ", LocalSymbol->getName());
1231
1232 if (ObjDelegate) {
1233 DebugStringTableSubsectionRef Strings = ObjDelegate->getStringTable();
1234 auto ExpectedProgram = Strings.getString(DefRangeSubfield.Program);
1235 if (!ExpectedProgram) {
1236 consumeError(ExpectedProgram.takeError());
1237 return llvm::make_error<CodeViewError>(
1238 "String table offset outside of bounds of String Table!");
1239 }
1240 W.printString("Program", *ExpectedProgram);
1241 }
1242 W.printNumber("OffsetInParent", DefRangeSubfield.OffsetInParent);
1243 printLocalVariableAddrRange(DefRangeSubfield.Range,
1244 DefRangeSubfield.getRelocationOffset());
1245 printLocalVariableAddrGap(DefRangeSubfield.Gaps);
1246 });
1247
1248 if (LVSymbol *Symbol = LocalSymbol) {
1249 Symbol->setHasCodeViewLocation();
1250 LocalSymbol = nullptr;
1251
1252 // Add location debug location. Operands: [Program, 0].
1253 dwarf::Attribute Attr = dwarf::Attribute(SymbolKind::S_DEFRANGE_SUBFIELD);
1254 uint64_t Operand1 = DefRangeSubfield.Program;
1255
1256 LocalVariableAddrRange Range = DefRangeSubfield.Range;
1258 Reader->linearAddress(Range.ISectStart, Range.OffsetStart);
1259
1260 Symbol->addLocation(Attr, Address, Address + Range.Range, 0, 0);
1261 Symbol->addLocationOperands(LVSmall(Attr), Operand1, /*Operand2=*/0);
1262 }
1263
1264 return Error::success();
1265}
1266
1267// S_DEFRANGE
1269 DefRangeSym &DefRange) {
1270 // DefRanges don't have types, just registers and code offsets.
1271 LLVM_DEBUG({
1272 if (LocalSymbol)
1273 W.getOStream() << formatv("Symbol: {0}, ", LocalSymbol->getName());
1274
1275 if (ObjDelegate) {
1276 DebugStringTableSubsectionRef Strings = ObjDelegate->getStringTable();
1277 auto ExpectedProgram = Strings.getString(DefRange.Program);
1278 if (!ExpectedProgram) {
1279 consumeError(ExpectedProgram.takeError());
1280 return llvm::make_error<CodeViewError>(
1281 "String table offset outside of bounds of String Table!");
1282 }
1283 W.printString("Program", *ExpectedProgram);
1284 }
1285 printLocalVariableAddrRange(DefRange.Range, DefRange.getRelocationOffset());
1286 printLocalVariableAddrGap(DefRange.Gaps);
1287 });
1288
1289 if (LVSymbol *Symbol = LocalSymbol) {
1290 Symbol->setHasCodeViewLocation();
1291 LocalSymbol = nullptr;
1292
1293 // Add location debug location. Operands: [Program, 0].
1294 dwarf::Attribute Attr = dwarf::Attribute(SymbolKind::S_DEFRANGE);
1295 uint64_t Operand1 = DefRange.Program;
1296
1299 Reader->linearAddress(Range.ISectStart, Range.OffsetStart);
1300
1301 Symbol->addLocation(Attr, Address, Address + Range.Range, 0, 0);
1302 Symbol->addLocationOperands(LVSmall(Attr), Operand1, /*Operand2=*/0);
1303 }
1304
1305 return Error::success();
1306}
1307
1308// S_FRAMEPROC
1310 FrameProcSym &FrameProc) {
1311 if (LVScope *Function = LogicalVisitor->getReaderScope()) {
1312 // S_FRAMEPROC contains extra information for the function described
1313 // by any of the previous generated records:
1314 // S_GPROC32, S_LPROC32, S_LPROC32_ID, S_GPROC32_ID.
1315
1316 // The generated sequence is:
1317 // S_GPROC32_ID ...
1318 // S_FRAMEPROC ...
1319
1320 // Collect additional inline flags for the current scope function.
1321 FrameProcedureOptions Flags = FrameProc.Flags;
1322 if (FrameProcedureOptions::MarkedInline ==
1323 (Flags & FrameProcedureOptions::MarkedInline))
1325 if (FrameProcedureOptions::Inlined ==
1326 (Flags & FrameProcedureOptions::Inlined))
1327 Function->setInlineCode(dwarf::DW_INL_inlined);
1328
1329 // To determine the symbol kind for any symbol declared in that function,
1330 // we can access the S_FRAMEPROC for the parent scope function. It contains
1331 // information about the local fp and param fp registers and compare with
1332 // the register in the S_REGREL32 to get a match.
1334 LocalFrameRegister = FrameProc.getLocalFramePtrReg(CPU);
1335 ParamFrameRegister = FrameProc.getParamFramePtrReg(CPU);
1336 }
1337
1338 return Error::success();
1339}
1340
1341// S_GDATA32, S_LDATA32, S_LMANDATA, S_GMANDATA
1343 LLVM_DEBUG({
1344 printTypeIndex("Type", Data.Type);
1345 W.printString("DisplayName", Data.Name);
1346 });
1347
1348 if (LVSymbol *Symbol = LogicalVisitor->CurrentSymbol) {
1350 if (ObjDelegate)
1351 ObjDelegate->getLinkageName(Data.getRelocationOffset(), Data.DataOffset,
1352 &LinkageName);
1353
1354 Symbol->setName(Data.Name);
1355 Symbol->setLinkageName(LinkageName);
1356
1357 // The MSVC generates local data as initialization for aggregates. It
1358 // contains the address for an initialization function.
1359 // The symbols contains the '$initializer$' pattern. Allow them only if
1360 // the '--internal=system' option is given.
1361 // 0 | S_LDATA32 `Struct$initializer$`
1362 // type = 0x1040 (void ()*)
1363 if (getReader().isSystemEntry(Symbol) && !options().getAttributeSystem()) {
1364 Symbol->resetIncludeInPrint();
1365 return Error::success();
1366 }
1367
1368 if (LVScope *Namespace = Shared->NamespaceDeduction.get(Data.Name)) {
1369 // The variable is already at different scope. In order to reflect
1370 // the correct parent, move it to the namespace.
1371 if (Symbol->getParentScope()->removeElement(Symbol))
1372 Namespace->addElement(Symbol);
1373 }
1374
1375 Symbol->setType(LogicalVisitor->getElement(StreamTPI, Data.Type));
1376 if (Record.kind() == SymbolKind::S_GDATA32)
1377 Symbol->setIsExternal();
1378 }
1379
1380 return Error::success();
1381}
1382
1383// S_INLINESITE
1386 LLVM_DEBUG({ printTypeIndex("Inlinee", InlineSite.Inlinee); });
1387
1388 if (LVScope *InlinedFunction = LogicalVisitor->CurrentScope) {
1389 LVScope *AbstractFunction = Reader->createScopeFunction();
1390 AbstractFunction->setIsSubprogram();
1391 AbstractFunction->setTag(dwarf::DW_TAG_subprogram);
1392 AbstractFunction->setInlineCode(dwarf::DW_INL_inlined);
1393 AbstractFunction->setIsInlinedAbstract();
1394 InlinedFunction->setReference(AbstractFunction);
1395
1396 LogicalVisitor->startProcessArgumentList();
1397 // 'Inlinee' is a Type ID.
1398 CVType CVFunctionType = Ids.getType(InlineSite.Inlinee);
1399 if (Error Err = LogicalVisitor->finishVisitation(
1400 CVFunctionType, InlineSite.Inlinee, AbstractFunction))
1401 return Err;
1402 LogicalVisitor->stopProcessArgumentList();
1403
1404 // For inlined functions set the linkage name to be the same as
1405 // the name. It used to find their lines and ranges.
1406 StringRef Name = AbstractFunction->getName();
1407 InlinedFunction->setName(Name);
1408 InlinedFunction->setLinkageName(Name);
1409
1410 // Process annotation bytes to calculate code and line offsets.
1411 if (Error Err = LogicalVisitor->inlineSiteAnnotation(
1412 AbstractFunction, InlinedFunction, InlineSite))
1413 return Err;
1414 }
1415
1416 return Error::success();
1417}
1418
1419// S_LOCAL
1421 LLVM_DEBUG({
1422 printTypeIndex("Type", Local.Type);
1423 W.printFlags("Flags", uint16_t(Local.Flags), getLocalFlagNames());
1424 W.printString("VarName", Local.Name);
1425 });
1426
1427 if (LVSymbol *Symbol = LogicalVisitor->CurrentSymbol) {
1428 Symbol->setName(Local.Name);
1429
1430 // Symbol was created as 'variable'; determine its real kind.
1431 Symbol->resetIsVariable();
1432
1433 // Be sure the 'this' symbol is marked as 'compiler generated'.
1434 if (bool(Local.Flags & LocalSymFlags::IsCompilerGenerated) ||
1435 Local.Name.equals("this")) {
1436 Symbol->setIsArtificial();
1437 Symbol->setIsParameter();
1438 } else {
1439 bool(Local.Flags & LocalSymFlags::IsParameter) ? Symbol->setIsParameter()
1440 : Symbol->setIsVariable();
1441 }
1442
1443 // Update correct debug information tag.
1444 if (Symbol->getIsParameter())
1445 Symbol->setTag(dwarf::DW_TAG_formal_parameter);
1446
1447 LVElement *Element = LogicalVisitor->getElement(StreamTPI, Local.Type);
1448 if (Element && Element->getIsScoped()) {
1449 // We have a local type. Find its parent function.
1450 LVScope *Parent = Symbol->getFunctionParent();
1451 // The element representing the type has been already finalized. If
1452 // the type is an aggregate type, its members have been already added.
1453 // As the type is local, its level will be changed.
1454 Parent->addElement(Element);
1455 Element->updateLevel(Parent);
1456 }
1457 Symbol->setType(Element);
1458
1459 // The CodeView records (S_DEFFRAME_*) describing debug location for
1460 // this symbol, do not have any direct reference to it. Those records
1461 // are emitted after this symbol. Record the current symbol.
1462 LocalSymbol = Symbol;
1463 }
1464
1465 return Error::success();
1466}
1467
1468// S_OBJNAME
1470 LLVM_DEBUG({
1471 W.printHex("Signature", ObjName.Signature);
1472 W.printString("ObjectName", ObjName.Name);
1473 });
1474
1475 CurrentObjectName = ObjName.Name;
1476 return Error::success();
1477}
1478
1479// S_GPROC32, S_LPROC32, S_LPROC32_ID, S_GPROC32_ID
1481 if (InFunctionScope)
1482 return llvm::make_error<CodeViewError>("Visiting a ProcSym while inside "
1483 "function scope!");
1484
1485 InFunctionScope = true;
1486
1487 LLVM_DEBUG({
1488 printTypeIndex("FunctionType", Proc.FunctionType);
1489 W.printHex("Segment", Proc.Segment);
1490 W.printFlags("Flags", static_cast<uint8_t>(Proc.Flags),
1492 W.printString("DisplayName", Proc.Name);
1493 });
1494
1495 // Clang and Microsoft generated different debug information records:
1496 // For functions definitions:
1497 // Clang: S_GPROC32 -> LF_FUNC_ID -> LF_PROCEDURE
1498 // Microsoft: S_GPROC32 -> LF_PROCEDURE
1499
1500 // For member function definition:
1501 // Clang: S_GPROC32 -> LF_MFUNC_ID -> LF_MFUNCTION
1502 // Microsoft: S_GPROC32 -> LF_MFUNCTION
1503 // In order to support both sequences, if we found LF_FUNCTION_ID, just
1504 // get the TypeIndex for LF_PROCEDURE.
1505
1506 // For the given test case, we have the sequence:
1507 // namespace NSP_local {
1508 // void foo_local() {
1509 // }
1510 // }
1511 //
1512 // 0x1000 | LF_STRING_ID String: NSP_local
1513 // 0x1002 | LF_PROCEDURE
1514 // return type = 0x0003 (void), # args = 0, param list = 0x1001
1515 // calling conv = cdecl, options = None
1516 // 0x1003 | LF_FUNC_ID
1517 // name = foo_local, type = 0x1002, parent scope = 0x1000
1518 // 0 | S_GPROC32_ID `NSP_local::foo_local`
1519 // type = `0x1003 (foo_local)`
1520 // 0x1004 | LF_STRING_ID String: suite
1521 // 0x1005 | LF_STRING_ID String: suite_local.cpp
1522 //
1523 // The LF_STRING_ID can hold different information:
1524 // 0x1000 - The enclosing namespace.
1525 // 0x1004 - The compile unit directory name.
1526 // 0x1005 - The compile unit name.
1527 //
1528 // Before deducting its scope, we need to evaluate its type and create any
1529 // associated namespaces.
1530 if (LVScope *Function = LogicalVisitor->CurrentScope) {
1532 if (ObjDelegate)
1533 ObjDelegate->getLinkageName(Proc.getRelocationOffset(), Proc.CodeOffset,
1534 &LinkageName);
1535
1536 // The line table can be accessed using the linkage name.
1538 Function->setName(Proc.Name);
1539 Function->setLinkageName(LinkageName);
1540
1541 if (options().getGeneralCollectRanges()) {
1542 // Record converted segment::offset addressing for this scope.
1543 LVAddress Addendum = Reader->getSymbolTableAddress(LinkageName);
1544 LVAddress LowPC =
1545 Reader->linearAddress(Proc.Segment, Proc.CodeOffset, Addendum);
1546 LVAddress HighPC = LowPC + Proc.CodeSize - 1;
1547 Function->addObject(LowPC, HighPC);
1548
1549 // If the scope is a function, add it to the public names.
1550 if ((options().getAttributePublics() || options().getPrintAnyLine()) &&
1551 !Function->getIsInlinedFunction())
1552 Reader->getCompileUnit()->addPublicName(Function, LowPC, HighPC);
1553 }
1554
1555 if (Function->getIsSystem() && !options().getAttributeSystem()) {
1556 Function->resetIncludeInPrint();
1557 return Error::success();
1558 }
1559
1560 TypeIndex TIFunctionType = Proc.FunctionType;
1561 if (TIFunctionType.isSimple())
1562 Function->setType(LogicalVisitor->getElement(StreamTPI, TIFunctionType));
1563 else {
1564 // We have to detect the correct stream, using the lexical parent
1565 // name, as there is not other obvious way to get the stream.
1566 // Normal function: LF_FUNC_ID (TPI)/(IPI)
1567 // LF_PROCEDURE (TPI)
1568 // Lambda function: LF_MFUNCTION (TPI)
1569 // Member function: LF_MFUNC_ID (TPI)/(IPI)
1570
1571 StringRef OuterComponent;
1572 std::tie(OuterComponent, std::ignore) = getInnerComponent(Proc.Name);
1573 TypeIndex TI = Shared->ForwardReferences.find(OuterComponent);
1574
1575 std::optional<CVType> CVFunctionType;
1576 auto GetRecordType = [&]() -> bool {
1577 CVFunctionType = Ids.tryGetType(TIFunctionType);
1578 if (!CVFunctionType)
1579 return false;
1580
1581 if (TI.isNoneType())
1582 // Normal function.
1583 if (CVFunctionType->kind() == LF_FUNC_ID)
1584 return true;
1585
1586 // Member function.
1587 return (CVFunctionType->kind() == LF_MFUNC_ID);
1588 };
1589
1590 // We can have a LF_FUNC_ID, LF_PROCEDURE or LF_MFUNCTION.
1591 if (!GetRecordType()) {
1592 CVFunctionType = Types.tryGetType(TIFunctionType);
1593 if (!CVFunctionType)
1594 return llvm::make_error<CodeViewError>("Invalid type index");
1595 }
1596
1597 if (Error Err = LogicalVisitor->finishVisitation(
1598 *CVFunctionType, TIFunctionType, Function))
1599 return Err;
1600 }
1601
1602 if (Record.kind() == SymbolKind::S_GPROC32 ||
1603 Record.kind() == SymbolKind::S_GPROC32_ID)
1604 Function->setIsExternal();
1605
1606 // We don't have a way to see if the symbol is compiler generated. Use
1607 // the linkage name, to detect `scalar deleting destructor' functions.
1608 std::string DemangledSymbol = demangle(std::string(LinkageName));
1609 if (DemangledSymbol.find("scalar deleting dtor") != std::string::npos) {
1610 Function->setIsArtificial();
1611 } else {
1612 // Clang generates global ctor and dtor names containing the substrings:
1613 // 'dynamic initializer for' and 'dynamic atexit destructor for'.
1614 if (DemangledSymbol.find("dynamic atexit destructor for") !=
1615 std::string::npos)
1616 Function->setIsArtificial();
1617 }
1618 }
1619
1620 return Error::success();
1621}
1622
1623// S_END
1625 ScopeEndSym &ScopeEnd) {
1626 InFunctionScope = false;
1627 return Error::success();
1628}
1629
1630// S_THUNK32
1632 if (InFunctionScope)
1633 return llvm::make_error<CodeViewError>("Visiting a Thunk32Sym while inside "
1634 "function scope!");
1635
1636 InFunctionScope = true;
1637
1638 LLVM_DEBUG({
1639 W.printHex("Segment", Thunk.Segment);
1640 W.printString("Name", Thunk.Name);
1641 });
1642
1643 if (LVScope *Function = LogicalVisitor->CurrentScope)
1644 Function->setName(Thunk.Name);
1645
1646 return Error::success();
1647}
1648
1649// S_UDT, S_COBOLUDT
1651 LLVM_DEBUG({
1652 printTypeIndex("Type", UDT.Type);
1653 W.printString("UDTName", UDT.Name);
1654 });
1655
1656 if (LVType *Type = LogicalVisitor->CurrentType) {
1657 if (LVScope *Namespace = Shared->NamespaceDeduction.get(UDT.Name)) {
1658 if (Type->getParentScope()->removeElement(Type))
1659 Namespace->addElement(Type);
1660 }
1661
1662 Type->setName(UDT.Name);
1663
1664 // We have to determine if the typedef is a real C/C++ definition or is
1665 // the S_UDT record that describe all the user defined types.
1666 // 0 | S_UDT `Name` original type = 0x1009
1667 // 0x1009 | LF_STRUCTURE `Name`
1668 // Ignore type definitions for RTTI types:
1669 // _s__RTTIBaseClassArray, _s__RTTIBaseClassDescriptor,
1670 // _s__RTTICompleteObjectLocator, _s__RTTIClassHierarchyDescriptor.
1672 Type->resetIncludeInPrint();
1673 else {
1674 StringRef RecordName = getRecordName(Types, UDT.Type);
1675 if (UDT.Name.equals(RecordName))
1676 Type->resetIncludeInPrint();
1677 Type->setType(LogicalVisitor->getElement(StreamTPI, UDT.Type));
1678 }
1679 }
1680
1681 return Error::success();
1682}
1683
1684// S_UNAMESPACE
1686 UsingNamespaceSym &UN) {
1687 LLVM_DEBUG({ W.printString("Namespace", UN.Name); });
1688 return Error::success();
1689}
1690
1691#undef DEBUG_TYPE
1692#define DEBUG_TYPE "CodeViewLogicalVisitor"
1693
1694//===----------------------------------------------------------------------===//
1695// Logical visitor.
1696//===----------------------------------------------------------------------===//
1698 InputFile &Input)
1699 : Reader(Reader), W(W), Input(Input) {
1700 // The LogicalVisitor connects the CodeViewReader with the visitors that
1701 // traverse the types, symbols, etc. Do any initialization that is needed.
1702 Shared = std::make_shared<LVShared>(Reader, this);
1703}
1704
1706 uint32_t StreamIdx) {
1707 codeview::printTypeIndex(W, FieldName, TI,
1708 StreamIdx == StreamTPI ? types() : ids());
1709}
1710
1712 LVElement *Element, uint32_t StreamIdx) {
1713 W.getOStream() << "\n";
1714 W.startLine() << formatTypeLeafKind(Record.kind());
1715 W.getOStream() << " (" << HexNumber(TI.getIndex()) << ")";
1716 W.getOStream() << " {\n";
1717 W.indent();
1718 W.printEnum("TypeLeafKind", unsigned(Record.kind()), ArrayRef(LeafTypeNames));
1719 printTypeIndex("TI", TI, StreamIdx);
1720 W.startLine() << "Element: " << HexNumber(Element->getOffset()) << " "
1721 << Element->getName() << "\n";
1722}
1723
1725 W.unindent();
1726 W.startLine() << "}\n";
1727}
1728
1730 LVElement *Element,
1731 uint32_t StreamIdx) {
1732 W.getOStream() << "\n";
1733 W.startLine() << formatTypeLeafKind(Record.Kind);
1734 W.getOStream() << " (" << HexNumber(TI.getIndex()) << ")";
1735 W.getOStream() << " {\n";
1736 W.indent();
1737 W.printEnum("TypeLeafKind", unsigned(Record.Kind), ArrayRef(LeafTypeNames));
1738 printTypeIndex("TI", TI, StreamIdx);
1739 W.startLine() << "Element: " << HexNumber(Element->getOffset()) << " "
1740 << Element->getName() << "\n";
1741}
1742
1744 W.unindent();
1745 W.startLine() << "}\n";
1746}
1747
1749 LLVM_DEBUG({
1750 printTypeIndex("\nTI", TI, StreamTPI);
1751 W.printNumber("Length", uint32_t(Record.content().size()));
1752 });
1753 return Error::success();
1754}
1755
1756// LF_ARGLIST (TPI)
1758 TypeIndex TI, LVElement *Element) {
1759 ArrayRef<TypeIndex> Indices = Args.getIndices();
1760 uint32_t Size = Indices.size();
1761 LLVM_DEBUG({
1762 printTypeBegin(Record, TI, Element, StreamTPI);
1763 W.printNumber("NumArgs", Size);
1764 ListScope Arguments(W, "Arguments");
1765 for (uint32_t I = 0; I < Size; ++I)
1766 printTypeIndex("ArgType", Indices[I], StreamTPI);
1768 });
1769
1770 LVScope *Function = static_cast<LVScope *>(Element);
1771 for (uint32_t Index = 0; Index < Size; ++Index) {
1772 TypeIndex ParameterType = Indices[Index];
1773 createParameter(ParameterType, StringRef(), Function);
1774 }
1775
1776 return Error::success();
1777}
1778
1779// LF_ARRAY (TPI)
1781 TypeIndex TI, LVElement *Element) {
1782 LLVM_DEBUG({
1783 printTypeBegin(Record, TI, Element, StreamTPI);
1784 printTypeIndex("ElementType", AT.getElementType(), StreamTPI);
1785 printTypeIndex("IndexType", AT.getIndexType(), StreamTPI);
1786 W.printNumber("SizeOf", AT.getSize());
1787 W.printString("Name", AT.getName());
1789 });
1790
1791 if (Element->getIsFinalized())
1792 return Error::success();
1793 Element->setIsFinalized();
1794
1795 LVScopeArray *Array = static_cast<LVScopeArray *>(Element);
1796 if (!Array)
1797 return Error::success();
1798
1799 Reader->getCompileUnit()->addElement(Array);
1800 TypeIndex TIElementType = AT.getElementType();
1801
1802 LVType *PrevSubrange = nullptr;
1804
1805 // As the logical view is modeled on DWARF, for each dimension we have to
1806 // create a DW_TAG_subrange_type, with dimension size.
1807 // The subrange type can be: unsigned __int32 or unsigned __int64.
1808 auto AddSubrangeType = [&](ArrayRecord &AR) {
1809 LVType *Subrange = Reader->createTypeSubrange();
1810 Subrange->setTag(dwarf::DW_TAG_subrange_type);
1811 Subrange->setType(getElement(StreamTPI, AR.getIndexType()));
1812 Subrange->setCount(AR.getSize());
1813 Subrange->setOffset(
1814 TIElementType.isSimple()
1815 ? (uint32_t)(TypeLeafKind)TIElementType.getSimpleKind()
1816 : TIElementType.getIndex());
1817 Array->addElement(Subrange);
1818
1819 if (PrevSubrange)
1820 if (int64_t Count = Subrange->getCount())
1821 PrevSubrange->setCount(PrevSubrange->getCount() / Count);
1822 PrevSubrange = Subrange;
1823 };
1824
1825 // Preserve the original TypeIndex; it would be updated in the case of:
1826 // - The array type contains qualifiers.
1827 // - In multidimensional arrays, the last LF_ARRAY entry contains the type.
1828 TypeIndex TIArrayType;
1829
1830 // For each dimension in the array, there is a LF_ARRAY entry. The last
1831 // entry contains the array type, which can be a LF_MODIFIER in the case
1832 // of the type being modified by a qualifier (const, etc).
1833 ArrayRecord AR(AT);
1834 CVType CVEntry = Record;
1835 while (CVEntry.kind() == LF_ARRAY) {
1836 // Create the subrange information, required by the logical view. Once
1837 // the array has been processed, the dimension sizes will updated, as
1838 // the sizes are a progression. For instance:
1839 // sizeof(int) = 4
1840 // int Array[2]; Sizes: 8 Dim: 8 / 4 -> [2]
1841 // int Array[2][3]; Sizes: 24, 12 Dim: 24 / 12 -> [2]
1842 // Dim: 12 / 4 -> [3]
1843 // int Array[2][3][4]; sizes: 96, 48, 16 Dim: 96 / 48 -> [2]
1844 // Dim: 48 / 16 -> [3]
1845 // Dim: 16 / 4 -> [4]
1846 AddSubrangeType(AR);
1847 TIArrayType = TIElementType;
1848
1849 // The current ElementType can be a modifier, in which case we need to
1850 // get the type being modified.
1851 // If TypeIndex is not a simple type, check if we have a qualified type.
1852 if (!TIElementType.isSimple()) {
1853 CVType CVElementType = Types.getType(TIElementType);
1854 if (CVElementType.kind() == LF_MODIFIER) {
1855 LVElement *QualifiedType =
1856 Shared->TypeRecords.find(StreamTPI, TIElementType);
1857 if (Error Err =
1858 finishVisitation(CVElementType, TIElementType, QualifiedType))
1859 return Err;
1860 // Get the TypeIndex of the type that the LF_MODIFIER modifies.
1861 TIElementType = getModifiedType(CVElementType);
1862 }
1863 }
1864 // Ends the traversal, as we have reached a simple type (int, char, etc).
1865 if (TIElementType.isSimple())
1866 break;
1867
1868 // Read next dimension linked entry, if any.
1869 CVEntry = Types.getType(TIElementType);
1871 const_cast<CVType &>(CVEntry), AR)) {
1872 consumeError(std::move(Err));
1873 break;
1874 }
1875 TIElementType = AR.getElementType();
1876 // NOTE: The typeindex has a value of: 0x0280.0000
1877 getTrueType(TIElementType);
1878 }
1879
1880 Array->setName(AT.getName());
1881 TIArrayType = Shared->ForwardReferences.remap(TIArrayType);
1882 Array->setType(getElement(StreamTPI, TIArrayType));
1883
1884 if (PrevSubrange)
1885 // In the case of an aggregate type (class, struct, union, interface),
1886 // get the aggregate size. As the original record is pointing to its
1887 // reference, we have to update it.
1888 if (uint64_t Size =
1889 isAggregate(CVEntry)
1890 ? getSizeInBytesForTypeRecord(Types.getType(TIArrayType))
1891 : getSizeInBytesForTypeIndex(TIElementType))
1892 PrevSubrange->setCount(PrevSubrange->getCount() / Size);
1893
1894 return Error::success();
1895}
1896
1897// LF_BITFIELD (TPI)
1899 TypeIndex TI, LVElement *Element) {
1900 LLVM_DEBUG({
1901 printTypeBegin(Record, TI, Element, StreamTPI);
1902 printTypeIndex("Type", TI, StreamTPI);
1903 W.printNumber("BitSize", BF.getBitSize());
1904 W.printNumber("BitOffset", BF.getBitOffset());
1906 });
1907
1908 Element->setType(getElement(StreamTPI, BF.getType()));
1909 Element->setBitSize(BF.getBitSize());
1910 return Error::success();
1911}
1912
1913// LF_BUILDINFO (TPI)/(IPI)
1915 TypeIndex TI, LVElement *Element) {
1916 LLVM_DEBUG({
1917 printTypeBegin(Record, TI, Element, StreamIPI);
1918 W.printNumber("NumArgs", static_cast<uint32_t>(BI.getArgs().size()));
1919 ListScope Arguments(W, "Arguments");
1920 for (TypeIndex Arg : BI.getArgs())
1921 printTypeIndex("ArgType", Arg, StreamIPI);
1923 });
1924
1925 // The given 'Element' refers to the current compilation unit.
1926 // All the args are references into the TPI/IPI stream.
1927 TypeIndex TIName = BI.getArgs()[BuildInfoRecord::BuildInfoArg::SourceFile];
1928 std::string Name = std::string(ids().getTypeName(TIName));
1929
1930 // There are cases where LF_BUILDINFO fields are empty.
1931 if (!Name.empty())
1932 Element->setName(Name);
1933
1934 return Error::success();
1935}
1936
1937// LF_CLASS, LF_STRUCTURE, LF_INTERFACE (TPI)
1939 TypeIndex TI, LVElement *Element) {
1940 LLVM_DEBUG({
1941 printTypeBegin(Record, TI, Element, StreamTPI);
1942 W.printNumber("MemberCount", Class.getMemberCount());
1943 printTypeIndex("FieldList", Class.getFieldList(), StreamTPI);
1944 printTypeIndex("DerivedFrom", Class.getDerivationList(), StreamTPI);
1945 printTypeIndex("VShape", Class.getVTableShape(), StreamTPI);
1946 W.printNumber("SizeOf", Class.getSize());
1947 W.printString("Name", Class.getName());
1948 if (Class.hasUniqueName())
1949 W.printString("UniqueName", Class.getUniqueName());
1951 });
1952
1953 if (Element->getIsFinalized())
1954 return Error::success();
1955 Element->setIsFinalized();
1956
1957 LVScopeAggregate *Scope = static_cast<LVScopeAggregate *>(Element);
1958 if (!Scope)
1959 return Error::success();
1960
1961 Scope->setName(Class.getName());
1962 if (Class.hasUniqueName())
1963 Scope->setLinkageName(Class.getUniqueName());
1964
1965 if (Class.isNested()) {
1966 Scope->setIsNested();
1967 createParents(Class.getName(), Scope);
1968 }
1969
1970 if (Class.isScoped())
1971 Scope->setIsScoped();
1972
1973 // Nested types will be added to their parents at creation. The forward
1974 // references are only processed to finish the referenced element creation.
1975 if (!(Class.isNested() || Class.isScoped())) {
1976 if (LVScope *Namespace = Shared->NamespaceDeduction.get(Class.getName()))
1977 Namespace->addElement(Scope);
1978 else
1979 Reader->getCompileUnit()->addElement(Scope);
1980 }
1981
1983 TypeIndex TIFieldList = Class.getFieldList();
1984 if (TIFieldList.isNoneType()) {
1985 TypeIndex ForwardType = Shared->ForwardReferences.find(Class.getName());
1986 if (!ForwardType.isNoneType()) {
1987 CVType CVReference = Types.getType(ForwardType);
1988 TypeRecordKind RK = static_cast<TypeRecordKind>(CVReference.kind());
1989 ClassRecord ReferenceRecord(RK);
1991 const_cast<CVType &>(CVReference), ReferenceRecord))
1992 return Err;
1993 TIFieldList = ReferenceRecord.getFieldList();
1994 }
1995 }
1996
1997 if (!TIFieldList.isNoneType()) {
1998 // Pass down the TypeIndex 'TI' for the aggregate containing the field list.
1999 CVType CVFieldList = Types.getType(TIFieldList);
2000 if (Error Err = finishVisitation(CVFieldList, TI, Scope))
2001 return Err;
2002 }
2003
2004 return Error::success();
2005}
2006
2007// LF_ENUM (TPI)
2009 TypeIndex TI, LVElement *Element) {
2010 LLVM_DEBUG({
2011 printTypeBegin(Record, TI, Element, StreamTPI);
2012 W.printNumber("NumEnumerators", Enum.getMemberCount());
2013 printTypeIndex("UnderlyingType", Enum.getUnderlyingType(), StreamTPI);
2014 printTypeIndex("FieldListType", Enum.getFieldList(), StreamTPI);
2015 W.printString("Name", Enum.getName());
2017 });
2018
2019 LVScopeEnumeration *Scope = static_cast<LVScopeEnumeration *>(Element);
2020 if (!Scope)
2021 return Error::success();
2022
2023 if (Scope->getIsFinalized())
2024 return Error::success();
2025 Scope->setIsFinalized();
2026
2027 // Set the name, as in the case of nested, it would determine the relation
2028 // to any potential parent, via the LF_NESTTYPE record.
2029 Scope->setName(Enum.getName());
2030 if (Enum.hasUniqueName())
2031 Scope->setLinkageName(Enum.getUniqueName());
2032
2033 Scope->setType(getElement(StreamTPI, Enum.getUnderlyingType()));
2034
2035 if (Enum.isNested()) {
2036 Scope->setIsNested();
2037 createParents(Enum.getName(), Scope);
2038 }
2039
2040 if (Enum.isScoped()) {
2041 Scope->setIsScoped();
2042 Scope->setIsEnumClass();
2043 }
2044
2045 // Nested types will be added to their parents at creation.
2046 if (!(Enum.isNested() || Enum.isScoped())) {
2047 if (LVScope *Namespace = Shared->NamespaceDeduction.get(Enum.getName()))
2048 Namespace->addElement(Scope);
2049 else
2050 Reader->getCompileUnit()->addElement(Scope);
2051 }
2052
2053 TypeIndex TIFieldList = Enum.getFieldList();
2054 if (!TIFieldList.isNoneType()) {
2056 CVType CVFieldList = Types.getType(TIFieldList);
2057 if (Error Err = finishVisitation(CVFieldList, TIFieldList, Scope))
2058 return Err;
2059 }
2060
2061 return Error::success();
2062}
2063
2064// LF_FIELDLIST (TPI)
2067 TypeIndex TI, LVElement *Element) {
2068 LLVM_DEBUG({
2069 printTypeBegin(Record, TI, Element, StreamTPI);
2071 });
2072
2073 if (Error Err = visitFieldListMemberStream(TI, Element, FieldList.Data))
2074 return Err;
2075
2076 return Error::success();
2077}
2078
2079// LF_FUNC_ID (TPI)/(IPI)
2081 TypeIndex TI, LVElement *Element) {
2082 // ParentScope and FunctionType are references into the TPI stream.
2083 LLVM_DEBUG({
2084 printTypeBegin(Record, TI, Element, StreamIPI);
2085 printTypeIndex("ParentScope", Func.getParentScope(), StreamTPI);
2086 printTypeIndex("FunctionType", Func.getFunctionType(), StreamTPI);
2087 W.printString("Name", Func.getName());
2089 });
2090
2091 // The TypeIndex (LF_PROCEDURE) returned by 'getFunctionType' is the
2092 // function propotype, we need to use the function definition.
2093 if (LVScope *FunctionDcl = static_cast<LVScope *>(Element)) {
2094 // For inlined functions, the inlined instance has been already processed
2095 // (all its information is contained in the Symbols section).
2096 // 'Element' points to the created 'abstract' (out-of-line) function.
2097 // Use the parent scope information to allocate it to the correct scope.
2099 TypeIndex TIParent = Func.getParentScope();
2100 if (FunctionDcl->getIsInlinedAbstract()) {
2101 FunctionDcl->setName(Func.getName());
2102 if (TIParent.isNoneType())
2103 Reader->getCompileUnit()->addElement(FunctionDcl);
2104 }
2105
2106 if (!TIParent.isNoneType()) {
2107 CVType CVParentScope = ids().getType(TIParent);
2108 if (Error Err = finishVisitation(CVParentScope, TIParent, FunctionDcl))
2109 return Err;
2110 }
2111
2112 TypeIndex TIFunctionType = Func.getFunctionType();
2113 CVType CVFunctionType = Types.getType(TIFunctionType);
2114 if (Error Err =
2115 finishVisitation(CVFunctionType, TIFunctionType, FunctionDcl))
2116 return Err;
2117
2118 FunctionDcl->setIsFinalized();
2119 }
2120
2121 return Error::success();
2122}
2123
2124// LF_LABEL (TPI)
2126 TypeIndex TI, LVElement *Element) {
2127 LLVM_DEBUG({
2128 printTypeBegin(Record, TI, Element, StreamTPI);
2130 });
2131 return Error::success();
2132}
2133
2134// LF_MFUNC_ID (TPI)/(IPI)
2136 TypeIndex TI, LVElement *Element) {
2137 // ClassType and FunctionType are references into the TPI stream.
2138 LLVM_DEBUG({
2139 printTypeBegin(Record, TI, Element, StreamIPI);
2140 printTypeIndex("ClassType", Id.getClassType(), StreamTPI);
2141 printTypeIndex("FunctionType", Id.getFunctionType(), StreamTPI);
2142 W.printString("Name", Id.getName());
2144 });
2145
2146 LVScope *FunctionDcl = static_cast<LVScope *>(Element);
2147 if (FunctionDcl->getIsInlinedAbstract()) {
2148 // For inlined functions, the inlined instance has been already processed
2149 // (all its information is contained in the Symbols section).
2150 // 'Element' points to the created 'abstract' (out-of-line) function.
2151 // Use the parent scope information to allocate it to the correct scope.
2152 if (LVScope *Class = static_cast<LVScope *>(
2153 Shared->TypeRecords.find(StreamTPI, Id.getClassType())))
2154 Class->addElement(FunctionDcl);
2155 }
2156
2157 TypeIndex TIFunctionType = Id.getFunctionType();
2158 CVType CVFunction = types().getType(TIFunctionType);
2159 if (Error Err = finishVisitation(CVFunction, TIFunctionType, Element))
2160 return Err;
2161
2162 return Error::success();
2163}
2164
2165// LF_MFUNCTION (TPI)
2168 LVElement *Element) {
2169 LLVM_DEBUG({
2170 printTypeBegin(Record, TI, Element, StreamTPI);
2171 printTypeIndex("ReturnType", MF.getReturnType(), StreamTPI);
2172 printTypeIndex("ClassType", MF.getClassType(), StreamTPI);
2173 printTypeIndex("ThisType", MF.getThisType(), StreamTPI);
2174 W.printNumber("NumParameters", MF.getParameterCount());
2175 printTypeIndex("ArgListType", MF.getArgumentList(), StreamTPI);
2176 W.printNumber("ThisAdjustment", MF.getThisPointerAdjustment());
2178 });
2179
2180 if (LVScope *MemberFunction = static_cast<LVScope *>(Element)) {
2182
2183 MemberFunction->setIsFinalized();
2184 MemberFunction->setType(getElement(StreamTPI, MF.getReturnType()));
2185 MemberFunction->setOffset(TI.getIndex());
2186 MemberFunction->setOffsetFromTypeIndex();
2187
2188 if (ProcessArgumentList) {
2189 ProcessArgumentList = false;
2190
2191 if (!MemberFunction->getIsStatic()) {
2192 LVElement *ThisPointer = getElement(StreamTPI, MF.getThisType());
2193 // When creating the 'this' pointer, check if it points to a reference.
2194 ThisPointer->setType(Class);
2195 LVSymbol *This =
2196 createParameter(ThisPointer, StringRef(), MemberFunction);
2197 This->setIsArtificial();
2198 }
2199
2200 // Create formal parameters.
2202 CVType CVArguments = Types.getType(MF.getArgumentList());
2203 if (Error Err = finishVisitation(CVArguments, MF.getArgumentList(),
2204 MemberFunction))
2205 return Err;
2206 }
2207 }
2208
2209 return Error::success();
2210}
2211
2212// LF_METHODLIST (TPI)
2214 MethodOverloadListRecord &Overloads,
2215 TypeIndex TI, LVElement *Element) {
2216 LLVM_DEBUG({
2217 printTypeBegin(Record, TI, Element, StreamTPI);
2219 });
2220
2221 for (OneMethodRecord &Method : Overloads.Methods) {
2223 Record.Kind = LF_METHOD;
2224 Method.Name = OverloadedMethodName;
2225 if (Error Err = visitKnownMember(Record, Method, TI, Element))
2226 return Err;
2227 }
2228
2229 return Error::success();
2230}
2231
2232// LF_MODIFIER (TPI)
2234 TypeIndex TI, LVElement *Element) {
2235 LLVM_DEBUG({
2236 printTypeBegin(Record, TI, Element, StreamTPI);
2237 printTypeIndex("ModifiedType", Mod.getModifiedType(), StreamTPI);
2239 });
2240
2241 // Create the modified type, which will be attached to the type(s) that
2242 // contains the modifiers.
2243 LVElement *ModifiedType = getElement(StreamTPI, Mod.getModifiedType());
2244
2245 // At this point the types recording the qualifiers do not have a
2246 // scope parent. They must be assigned to the current compile unit.
2248
2249 // The incoming element does not have a defined kind. Use the given
2250 // modifiers to complete its type. A type can have more than one modifier;
2251 // in that case, we have to create an extra type to have the other modifier.
2252 LVType *LastLink = static_cast<LVType *>(Element);
2253 if (!LastLink->getParentScope())
2254 CompileUnit->addElement(LastLink);
2255
2256 bool SeenModifier = false;
2257 uint16_t Mods = static_cast<uint16_t>(Mod.getModifiers());
2258 if (Mods & uint16_t(ModifierOptions::Const)) {
2259 SeenModifier = true;
2260 LastLink->setTag(dwarf::DW_TAG_const_type);
2261 LastLink->setIsConst();
2262 LastLink->setName("const");
2263 }
2264 if (Mods & uint16_t(ModifierOptions::Volatile)) {
2265 if (SeenModifier) {
2266 LVType *Volatile = Reader->createType();
2267 Volatile->setIsModifier();
2268 LastLink->setType(Volatile);
2269 LastLink = Volatile;
2270 CompileUnit->addElement(LastLink);
2271 }
2272 LastLink->setTag(dwarf::DW_TAG_volatile_type);
2273 LastLink->setIsVolatile();
2274 LastLink->setName("volatile");
2275 }
2276 if (Mods & uint16_t(ModifierOptions::Unaligned)) {
2277 if (SeenModifier) {
2278 LVType *Unaligned = Reader->createType();
2279 Unaligned->setIsModifier();
2280 LastLink->setType(Unaligned);
2281 LastLink = Unaligned;
2282 CompileUnit->addElement(LastLink);
2283 }
2285 LastLink->setIsUnaligned();
2286 LastLink->setName("unaligned");
2287 }
2288
2289 LastLink->setType(ModifiedType);
2290 return Error::success();
2291}
2292
2293// LF_POINTER (TPI)
2295 TypeIndex TI, LVElement *Element) {
2296 LLVM_DEBUG({
2297 printTypeBegin(Record, TI, Element, StreamTPI);
2298 printTypeIndex("PointeeType", Ptr.getReferentType(), StreamTPI);
2299 W.printNumber("IsFlat", Ptr.isFlat());
2300 W.printNumber("IsConst", Ptr.isConst());
2301 W.printNumber("IsVolatile", Ptr.isVolatile());
2302 W.printNumber("IsUnaligned", Ptr.isUnaligned());
2303 W.printNumber("IsRestrict", Ptr.isRestrict());
2304 W.printNumber("IsThisPtr&", Ptr.isLValueReferenceThisPtr());
2305 W.printNumber("IsThisPtr&&", Ptr.isRValueReferenceThisPtr());
2306 W.printNumber("SizeOf", Ptr.getSize());
2307
2308 if (Ptr.isPointerToMember()) {
2309 const MemberPointerInfo &MI = Ptr.getMemberInfo();
2310 printTypeIndex("ClassType", MI.getContainingType(), StreamTPI);
2311 }
2313 });
2314
2315 // Find the pointed-to type.
2316 LVType *Pointer = static_cast<LVType *>(Element);
2317 LVElement *Pointee = nullptr;
2318
2319 PointerMode Mode = Ptr.getMode();
2320 Pointee = Ptr.isPointerToMember()
2321 ? Shared->TypeRecords.find(StreamTPI, Ptr.getReferentType())
2322 : getElement(StreamTPI, Ptr.getReferentType());
2323
2324 // At this point the types recording the qualifiers do not have a
2325 // scope parent. They must be assigned to the current compile unit.
2327
2328 // Order for the different modifiers:
2329 // <restrict> <pointer, Reference, ValueReference> <const, volatile>
2330 // Const and volatile already processed.
2331 bool SeenModifier = false;
2332 LVType *LastLink = Pointer;
2333 if (!LastLink->getParentScope())
2334 CompileUnit->addElement(LastLink);
2335
2336 if (Ptr.isRestrict()) {
2337 SeenModifier = true;
2338 LVType *Restrict = Reader->createType();
2339 Restrict->setTag(dwarf::DW_TAG_restrict_type);
2340 Restrict->setIsRestrict();
2341 Restrict->setName("restrict");
2342 LastLink->setType(Restrict);
2343 LastLink = Restrict;
2344 CompileUnit->addElement(LastLink);
2345 }
2346 if (Mode == PointerMode::LValueReference) {
2347 if (SeenModifier) {
2348 LVType *LReference = Reader->createType();
2349 LReference->setIsModifier();
2350 LastLink->setType(LReference);
2351 LastLink = LReference;
2352 CompileUnit->addElement(LastLink);
2353 }
2354 LastLink->setTag(dwarf::DW_TAG_reference_type);
2355 LastLink->setIsReference();
2356 LastLink->setName("&");
2357 }
2358 if (Mode == PointerMode::RValueReference) {
2359 if (SeenModifier) {
2360 LVType *RReference = Reader->createType();
2361 RReference->setIsModifier();
2362 LastLink->setType(RReference);
2363 LastLink = RReference;
2364 CompileUnit->addElement(LastLink);
2365 }
2366 LastLink->setTag(dwarf::DW_TAG_rvalue_reference_type);
2367 LastLink->setIsRvalueReference();
2368 LastLink->setName("&&");
2369 }
2370
2371 // When creating the pointer, check if it points to a reference.
2372 LastLink->setType(Pointee);
2373 return Error::success();
2374}
2375
2376// LF_PROCEDURE (TPI)
2378 TypeIndex TI, LVElement *Element) {
2379 LLVM_DEBUG({
2380 printTypeBegin(Record, TI, Element, StreamTPI);
2381 printTypeIndex("ReturnType", Proc.getReturnType(), StreamTPI);
2382 W.printNumber("NumParameters", Proc.getParameterCount());
2383 printTypeIndex("ArgListType", Proc.getArgumentList(), StreamTPI);
2385 });
2386
2387 // There is no need to traverse the argument list, as the CodeView format
2388 // declares the parameters as a 'S_LOCAL' symbol tagged as parameter.
2389 // Only process parameters when dealing with inline functions.
2390 if (LVScope *FunctionDcl = static_cast<LVScope *>(Element)) {
2391 FunctionDcl->setType(getElement(StreamTPI, Proc.getReturnType()));
2392
2393 if (ProcessArgumentList) {
2394 ProcessArgumentList = false;
2395 // Create formal parameters.
2397 CVType CVArguments = Types.getType(Proc.getArgumentList());
2398 if (Error Err = finishVisitation(CVArguments, Proc.getArgumentList(),
2399 FunctionDcl))
2400 return Err;
2401 }
2402 }
2403
2404 return Error::success();
2405}
2406
2407// LF_UNION (TPI)
2409 TypeIndex TI, LVElement *Element) {
2410 LLVM_DEBUG({
2411 printTypeBegin(Record, TI, Element, StreamTPI);
2412 W.printNumber("MemberCount", Union.getMemberCount());
2413 printTypeIndex("FieldList", Union.getFieldList(), StreamTPI);
2414 W.printNumber("SizeOf", Union.getSize());
2415 W.printString("Name", Union.getName());
2416 if (Union.hasUniqueName())
2417 W.printString("UniqueName", Union.getUniqueName());
2419 });
2420
2421 LVScopeAggregate *Scope = static_cast<LVScopeAggregate *>(Element);
2422 if (!Scope)
2423 return Error::success();
2424
2425 if (Scope->getIsFinalized())
2426 return Error::success();
2427 Scope->setIsFinalized();
2428
2429 Scope->setName(Union.getName());
2430 if (Union.hasUniqueName())
2431 Scope->setLinkageName(Union.getUniqueName());
2432
2433 if (Union.isNested()) {
2434 Scope->setIsNested();
2435 createParents(Union.getName(), Scope);
2436 } else {
2437 if (LVScope *Namespace = Shared->NamespaceDeduction.get(Union.getName()))
2438 Namespace->addElement(Scope);
2439 else
2440 Reader->getCompileUnit()->addElement(Scope);
2441 }
2442
2443 if (!Union.getFieldList().isNoneType()) {
2445 // Pass down the TypeIndex 'TI' for the aggregate containing the field list.
2446 CVType CVFieldList = Types.getType(Union.getFieldList());
2447 if (Error Err = finishVisitation(CVFieldList, TI, Scope))
2448 return Err;
2449 }
2450
2451 return Error::success();
2452}
2453
2454// LF_TYPESERVER2 (TPI)
2456 TypeIndex TI, LVElement *Element) {
2457 LLVM_DEBUG({
2458 printTypeBegin(Record, TI, Element, StreamTPI);
2459 W.printString("Guid", formatv("{0}", TS.getGuid()).str());
2460 W.printNumber("Age", TS.getAge());
2461 W.printString("Name", TS.getName());
2463 });
2464 return Error::success();
2465}
2466
2467// LF_VFTABLE (TPI)
2469 TypeIndex TI, LVElement *Element) {
2470 LLVM_DEBUG({
2471 printTypeBegin(Record, TI, Element, StreamTPI);
2472 printTypeIndex("CompleteClass", VFT.getCompleteClass(), StreamTPI);
2473 printTypeIndex("OverriddenVFTable", VFT.getOverriddenVTable(), StreamTPI);
2474 W.printHex("VFPtrOffset", VFT.getVFPtrOffset());
2475 W.printString("VFTableName", VFT.getName());
2476 for (const StringRef &N : VFT.getMethodNames())
2477 W.printString("MethodName", N);
2479 });
2480 return Error::success();
2481}
2482
2483// LF_VTSHAPE (TPI)
2485 VFTableShapeRecord &Shape,
2486 TypeIndex TI, LVElement *Element) {
2487 LLVM_DEBUG({
2488 printTypeBegin(Record, TI, Element, StreamTPI);
2489 W.printNumber("VFEntryCount", Shape.getEntryCount());
2491 });
2492 return Error::success();
2493}
2494
2495// LF_SUBSTR_LIST (TPI)/(IPI)
2497 StringListRecord &Strings,
2498 TypeIndex TI, LVElement *Element) {
2499 // All the indices are references into the TPI/IPI stream.
2500 LLVM_DEBUG({
2501 printTypeBegin(Record, TI, Element, StreamIPI);
2502 ArrayRef<TypeIndex> Indices = Strings.getIndices();
2503 uint32_t Size = Indices.size();
2504 W.printNumber("NumStrings", Size);
2505 ListScope Arguments(W, "Strings");
2506 for (uint32_t I = 0; I < Size; ++I)
2507 printTypeIndex("String", Indices[I], StreamIPI);
2509 });
2510 return Error::success();
2511}
2512
2513// LF_STRING_ID (TPI)/(IPI)
2515 TypeIndex TI, LVElement *Element) {
2516 // All args are references into the TPI/IPI stream.
2517 LLVM_DEBUG({
2518 printTypeIndex("\nTI", TI, StreamIPI);
2519 printTypeIndex("Id", String.getId(), StreamIPI);
2520 W.printString("StringData", String.getString());
2521 });
2522
2523 if (LVScope *Namespace = Shared->NamespaceDeduction.get(
2524 String.getString(), /*CheckScope=*/false)) {
2525 // The function is already at different scope. In order to reflect
2526 // the correct parent, move it to the namespace.
2527 if (LVScope *Scope = Element->getParentScope())
2528 Scope->removeElement(Element);
2529 Namespace->addElement(Element);
2530 }
2531
2532 return Error::success();
2533}
2534
2535// LF_UDT_SRC_LINE (TPI)/(IPI)
2537 UdtSourceLineRecord &SourceLine,
2538 TypeIndex TI, LVElement *Element) {
2539 // All args are references into the TPI/IPI stream.
2540 LLVM_DEBUG({
2541 printTypeIndex("\nTI", TI, StreamIPI);
2542 printTypeIndex("UDT", SourceLine.getUDT(), StreamIPI);
2543 printTypeIndex("SourceFile", SourceLine.getSourceFile(), StreamIPI);
2544 W.printNumber("LineNumber", SourceLine.getLineNumber());
2545 });
2546 return Error::success();
2547}
2548
2549// LF_UDT_MOD_SRC_LINE (TPI)/(IPI)
2551 UdtModSourceLineRecord &ModSourceLine,
2552 TypeIndex TI, LVElement *Element) {
2553 // All args are references into the TPI/IPI stream.
2554 LLVM_DEBUG({
2555 printTypeBegin(Record, TI, Element, StreamIPI);
2556 printTypeIndex("\nTI", TI, StreamIPI);
2557 printTypeIndex("UDT", ModSourceLine.getUDT(), StreamIPI);
2558 printTypeIndex("SourceFile", ModSourceLine.getSourceFile(), StreamIPI);
2559 W.printNumber("LineNumber", ModSourceLine.getLineNumber());
2560 W.printNumber("Module", ModSourceLine.getModule());
2562 });
2563 return Error::success();
2564}
2565
2566// LF_PRECOMP (TPI)
2568 TypeIndex TI, LVElement *Element) {
2569 LLVM_DEBUG({
2570 printTypeBegin(Record, TI, Element, StreamTPI);
2571 W.printHex("StartIndex", Precomp.getStartTypeIndex());
2572 W.printHex("Count", Precomp.getTypesCount());
2573 W.printHex("Signature", Precomp.getSignature());
2574 W.printString("PrecompFile", Precomp.getPrecompFilePath());
2576 });
2577 return Error::success();
2578}
2579
2580// LF_ENDPRECOMP (TPI)
2582 EndPrecompRecord &EndPrecomp,
2583 TypeIndex TI, LVElement *Element) {
2584 LLVM_DEBUG({
2585 printTypeBegin(Record, TI, Element, StreamTPI);
2586 W.printHex("Signature", EndPrecomp.getSignature());
2588 });
2589 return Error::success();
2590}
2591
2593 TypeIndex TI) {
2594 LLVM_DEBUG({ W.printHex("UnknownMember", unsigned(Record.Kind)); });
2595 return Error::success();
2596}
2597
2598// LF_BCLASS, LF_BINTERFACE
2601 LVElement *Element) {
2602 LLVM_DEBUG({
2603 printMemberBegin(Record, TI, Element, StreamTPI);
2604 printTypeIndex("BaseType", Base.getBaseType(), StreamTPI);
2605 W.printHex("BaseOffset", Base.getBaseOffset());
2607 });
2608
2609 createElement(Record.Kind);
2610 if (LVSymbol *Symbol = CurrentSymbol) {
2611 LVElement *BaseClass = getElement(StreamTPI, Base.getBaseType());
2612 Symbol->setName(BaseClass->getName());
2613 Symbol->setType(BaseClass);
2614 Symbol->setAccessibilityCode(Base.getAccess());
2615 static_cast<LVScope *>(Element)->addElement(Symbol);
2616 }
2617
2618 return Error::success();
2619}
2620
2621// LF_MEMBER
2624 LVElement *Element) {
2625 LLVM_DEBUG({
2626 printMemberBegin(Record, TI, Element, StreamTPI);
2627 printTypeIndex("Type", Field.getType(), StreamTPI);
2628 W.printHex("FieldOffset", Field.getFieldOffset());
2629 W.printString("Name", Field.getName());
2631 });
2632
2633 // Create the data member.
2634 createDataMember(Record, static_cast<LVScope *>(Element), Field.getName(),
2635 Field.getType(), Field.getAccess());
2636 return Error::success();
2637}
2638
2639// LF_ENUMERATE
2642 LVElement *Element) {
2643 LLVM_DEBUG({
2644 printMemberBegin(Record, TI, Element, StreamTPI);
2645 W.printNumber("EnumValue", Enum.getValue());
2646 W.printString("Name", Enum.getName());
2648 });
2649
2650 createElement(Record.Kind);
2651 if (LVType *Type = CurrentType) {
2652 Type->setName(Enum.getName());
2654 Enum.getValue().toString(Value, 16, true, true);
2655 Type->setValue(Value);
2656 static_cast<LVScope *>(Element)->addElement(CurrentType);
2657 }
2658
2659 return Error::success();
2660}
2661
2662// LF_INDEX
2665 TypeIndex TI, LVElement *Element) {
2666 LLVM_DEBUG({
2667 printMemberBegin(Record, TI, Element, StreamTPI);
2668 printTypeIndex("ContinuationIndex", Cont.getContinuationIndex(), StreamTPI);
2670 });
2671 return Error::success();
2672}
2673
2674// LF_NESTTYPE
2677 LVElement *Element) {
2678 LLVM_DEBUG({
2679 printMemberBegin(Record, TI, Element, StreamTPI);
2680 printTypeIndex("Type", Nested.getNestedType(), StreamTPI);
2681 W.printString("Name", Nested.getName());
2683 });
2684
2685 if (LVElement *Typedef = createElement(SymbolKind::S_UDT)) {
2686 Typedef->setName(Nested.getName());
2687 LVElement *NestedType = getElement(StreamTPI, Nested.getNestedType());
2688 Typedef->setType(NestedType);
2689 LVScope *Scope = static_cast<LVScope *>(Element);
2690 Scope->addElement(Typedef);
2691
2692 if (NestedType && NestedType->getIsNested()) {
2693 // 'Element' is an aggregate type that may contains this nested type
2694 // definition. Used their scoped names, to decide on their relationship.
2695 StringRef RecordName = getRecordName(types(), TI);
2696
2697 StringRef NestedTypeName = NestedType->getName();
2698 if (NestedTypeName.size() && RecordName.size()) {
2699 StringRef OuterComponent;
2700 std::tie(OuterComponent, std::ignore) =
2701 getInnerComponent(NestedTypeName);
2702 // We have an already created nested type. Add it to the current scope
2703 // and update all its children if any.
2704 if (OuterComponent.size() && OuterComponent.equals(RecordName)) {
2705 if (!NestedType->getIsScopedAlready()) {
2706 Scope->addElement(NestedType);
2707 NestedType->setIsScopedAlready();
2708 NestedType->updateLevel(Scope);
2709 }
2710 Typedef->resetIncludeInPrint();
2711 }
2712 }
2713 }
2714 }
2715
2716 return Error::success();
2717}
2718
2719// LF_ONEMETHOD
2721 OneMethodRecord &Method, TypeIndex TI,
2722 LVElement *Element) {
2723 LLVM_DEBUG({
2724 printMemberBegin(Record, TI, Element, StreamTPI);
2725 printTypeIndex("Type", Method.getType(), StreamTPI);
2726 // If virtual, then read the vftable offset.
2727 if (Method.isIntroducingVirtual())
2728 W.printHex("VFTableOffset", Method.getVFTableOffset());
2729 W.printString("Name", Method.getName());
2731 });
2732
2733 // All the LF_ONEMETHOD objects share the same type description.
2734 // We have to create a scope object for each one and get the required
2735 // information from the LF_MFUNCTION object.
2736 ProcessArgumentList = true;
2737 if (LVElement *MemberFunction = createElement(TypeLeafKind::LF_ONEMETHOD)) {
2738 MemberFunction->setIsFinalized();
2739 static_cast<LVScope *>(Element)->addElement(MemberFunction);
2740
2741 MemberFunction->setName(Method.getName());
2742 MemberFunction->setAccessibilityCode(Method.getAccess());
2743
2744 MethodKind Kind = Method.getMethodKind();
2745 if (Kind == MethodKind::Static)
2746 MemberFunction->setIsStatic();
2747 MemberFunction->setVirtualityCode(Kind);
2748
2749 MethodOptions Flags = Method.Attrs.getFlags();
2750 if (MethodOptions::CompilerGenerated ==
2751 (Flags & MethodOptions::CompilerGenerated))
2752 MemberFunction->setIsArtificial();
2753
2755 CVType CVMethodType = Types.getType(Method.getType());
2756 if (Error Err =
2757 finishVisitation(CVMethodType, Method.getType(), MemberFunction))
2758 return Err;
2759 }
2760 ProcessArgumentList = false;
2761
2762 return Error::success();
2763}
2764
2765// LF_METHOD
2767 OverloadedMethodRecord &Method,
2768 TypeIndex TI, LVElement *Element) {
2769 LLVM_DEBUG({
2770 printMemberBegin(Record, TI, Element, StreamTPI);
2771 W.printHex("MethodCount", Method.getNumOverloads());
2772 printTypeIndex("MethodListIndex", Method.getMethodList(), StreamTPI);
2773 W.printString("Name", Method.getName());
2775 });
2776
2777 // Record the overloaded method name, which will be used during the
2778 // traversal of the method list.
2780 OverloadedMethodName = Method.getName();
2781 CVType CVMethods = Types.getType(Method.getMethodList());
2782 if (Error Err = finishVisitation(CVMethods, Method.getMethodList(), Element))
2783 return Err;
2784
2785 return Error::success();
2786}
2787
2788// LF_STMEMBER
2791 TypeIndex TI, LVElement *Element) {
2792 LLVM_DEBUG({
2793 printMemberBegin(Record, TI, Element, StreamTPI);
2794 printTypeIndex("Type", Field.getType(), StreamTPI);
2795 W.printString("Name", Field.getName());
2797 });
2798
2799 // Create the data member.
2800 createDataMember(Record, static_cast<LVScope *>(Element), Field.getName(),
2801 Field.getType(), Field.getAccess());
2802 return Error::success();
2803}
2804
2805// LF_VFUNCTAB
2807 VFPtrRecord &VFTable, TypeIndex TI,
2808 LVElement *Element) {
2809 LLVM_DEBUG({
2810 printMemberBegin(Record, TI, Element, StreamTPI);
2811 printTypeIndex("Type", VFTable.getType(), StreamTPI);
2813 });
2814 return Error::success();
2815}
2816
2817// LF_VBCLASS, LF_IVBCLASS
2820 TypeIndex TI, LVElement *Element) {
2821 LLVM_DEBUG({
2822 printMemberBegin(Record, TI, Element, StreamTPI);
2823 printTypeIndex("BaseType", Base.getBaseType(), StreamTPI);
2824 printTypeIndex("VBPtrType", Base.getVBPtrType(), StreamTPI);
2825 W.printHex("VBPtrOffset", Base.getVBPtrOffset());
2826 W.printHex("VBTableIndex", Base.getVTableIndex());
2828 });
2829
2830 createElement(Record.Kind);
2831 if (LVSymbol *Symbol = CurrentSymbol) {
2832 LVElement *BaseClass = getElement(StreamTPI, Base.getBaseType());
2833 Symbol->setName(BaseClass->getName());
2834 Symbol->setType(BaseClass);
2835 Symbol->setAccessibilityCode(Base.getAccess());
2836 Symbol->setVirtualityCode(MethodKind::Virtual);
2837 static_cast<LVScope *>(Element)->addElement(Symbol);
2838 }
2839
2840 return Error::success();
2841}
2842
2844 TypeVisitorCallbacks &Callbacks,
2845 TypeIndex TI, LVElement *Element) {
2846 if (Error Err = Callbacks.visitMemberBegin(Record))
2847 return Err;
2848
2849 switch (Record.Kind) {
2850 default:
2851 if (Error Err = Callbacks.visitUnknownMember(Record))
2852 return Err;
2853 break;
2854#define MEMBER_RECORD(EnumName, EnumVal, Name) \
2855 case EnumName: { \
2856 if (Error Err = \
2857 visitKnownMember<Name##Record>(Record, Callbacks, TI, Element)) \
2858 return Err; \
2859 break; \
2860 }
2861#define MEMBER_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName) \
2862 MEMBER_RECORD(EnumVal, EnumVal, AliasName)
2863#define TYPE_RECORD(EnumName, EnumVal, Name)
2864#define TYPE_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName)
2865#include "llvm/DebugInfo/CodeView/CodeViewTypes.def"
2866 }
2867
2868 if (Error Err = Callbacks.visitMemberEnd(Record))
2869 return Err;
2870
2871 return Error::success();
2872}
2873
2875 LVElement *Element) {
2876 switch (Record.kind()) {
2877 default:
2878 if (Error Err = visitUnknownType(Record, TI))
2879 return Err;
2880 break;
2881#define TYPE_RECORD(EnumName, EnumVal, Name) \
2882 case EnumName: { \
2883 if (Error Err = visitKnownRecord<Name##Record>(Record, TI, Element)) \
2884 return Err; \
2885 break; \
2886 }
2887#define TYPE_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName) \
2888 TYPE_RECORD(EnumVal, EnumVal, AliasName)
2889#define MEMBER_RECORD(EnumName, EnumVal, Name)
2890#define MEMBER_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName)
2891#include "llvm/DebugInfo/CodeView/CodeViewTypes.def"
2892 }
2893
2894 return Error::success();
2895}
2896
2897// Customized version of 'FieldListVisitHelper'.
2898Error LVLogicalVisitor::visitFieldListMemberStream(
2901 BinaryStreamReader Reader(Stream);
2902 FieldListDeserializer Deserializer(Reader);
2904 Pipeline.addCallbackToPipeline(Deserializer);
2905
2906 TypeLeafKind Leaf;
2907 while (!Reader.empty()) {
2908 if (Error Err = Reader.readEnum(Leaf))
2909 return Err;
2910
2912 Record.Kind = Leaf;
2913 if (Error Err = visitMemberRecord(Record, Pipeline, TI, Element))
2914 return Err;
2915 }
2916
2917 return Error::success();
2918}
2919
2921 // The CodeView specifications does not treat S_COMPILE2 and S_COMPILE3
2922 // as symbols that open a scope. The CodeView reader, treat them in a
2923 // similar way as DWARF. As there is no a symbole S_END to close the
2924 // compile unit, we need to check for the next compile unit.
2925 if (IsCompileUnit) {
2926 if (!ScopeStack.empty())
2927 popScope();
2928 InCompileUnitScope = true;
2929 }
2930
2931 pushScope(Scope);
2932 ReaderParent->addElement(Scope);
2933}
2934
2936 ReaderScope->addElement(Symbol);
2937}
2938
2940 ReaderScope->addElement(Type);
2941}
2942
2944 CurrentScope = nullptr;
2945 CurrentSymbol = nullptr;
2946 CurrentType = nullptr;
2947
2949 CurrentType = Reader->createType();
2950 CurrentType->setIsBase();
2951 CurrentType->setTag(dwarf::DW_TAG_base_type);
2952 if (options().getAttributeBase())
2953 CurrentType->setIncludeInPrint();
2954 return CurrentType;
2955 }
2956
2957 switch (Kind) {
2958 // Types.
2959 case TypeLeafKind::LF_ENUMERATE:
2960 CurrentType = Reader->createTypeEnumerator();
2961 CurrentType->setTag(dwarf::DW_TAG_enumerator);
2962 return CurrentType;
2963 case TypeLeafKind::LF_MODIFIER:
2964 CurrentType = Reader->createType();
2965 CurrentType->setIsModifier();
2966 return CurrentType;
2967 case TypeLeafKind::LF_POINTER:
2968 CurrentType = Reader->createType();
2969 CurrentType->setIsPointer();
2970 CurrentType->setName("*");
2971 CurrentType->setTag(dwarf::DW_TAG_pointer_type);
2972 return CurrentType;
2973
2974 // Symbols.
2975 case TypeLeafKind::LF_BCLASS:
2976 case TypeLeafKind::LF_IVBCLASS:
2977 case TypeLeafKind::LF_VBCLASS:
2978 CurrentSymbol = Reader->createSymbol();
2979 CurrentSymbol->setTag(dwarf::DW_TAG_inheritance);
2980 CurrentSymbol->setIsInheritance();
2981 return CurrentSymbol;
2982 case TypeLeafKind::LF_MEMBER:
2983 case TypeLeafKind::LF_STMEMBER:
2984 CurrentSymbol = Reader->createSymbol();
2985 CurrentSymbol->setIsMember();
2986 CurrentSymbol->setTag(dwarf::DW_TAG_member);
2987 return CurrentSymbol;
2988
2989 // Scopes.
2990 case TypeLeafKind::LF_ARRAY:
2991 CurrentScope = Reader->createScopeArray();
2992 CurrentScope->setTag(dwarf::DW_TAG_array_type);
2993 return CurrentScope;
2994 case TypeLeafKind::LF_CLASS:
2995 CurrentScope = Reader->createScopeAggregate();
2996 CurrentScope->setTag(dwarf::DW_TAG_class_type);
2997 CurrentScope->setIsClass();
2998 return CurrentScope;
2999 case TypeLeafKind::LF_ENUM:
3000 CurrentScope = Reader->createScopeEnumeration();
3001 CurrentScope->setTag(dwarf::DW_TAG_enumeration_type);
3002 return CurrentScope;
3003 case TypeLeafKind::LF_METHOD:
3004 case TypeLeafKind::LF_ONEMETHOD:
3005 case TypeLeafKind::LF_PROCEDURE:
3006 CurrentScope = Reader->createScopeFunction();
3007 CurrentScope->setIsSubprogram();
3008 CurrentScope->setTag(dwarf::DW_TAG_subprogram);
3009 return CurrentScope;
3010 case TypeLeafKind::LF_STRUCTURE:
3011 CurrentScope = Reader->createScopeAggregate();
3012 CurrentScope->setIsStructure();
3013 CurrentScope->setTag(dwarf::DW_TAG_structure_type);
3014 return CurrentScope;
3015 case TypeLeafKind::LF_UNION:
3016 CurrentScope = Reader->createScopeAggregate();
3017 CurrentScope->setIsUnion();
3018 CurrentScope->setTag(dwarf::DW_TAG_union_type);
3019 return CurrentScope;
3020 default:
3021 // If '--internal=tag' and '--print=warning' are specified in the command
3022 // line, we record and print each seen 'TypeLeafKind'.
3023 break;
3024 }
3025 return nullptr;
3026}
3027
3029 CurrentScope = nullptr;
3030 CurrentSymbol = nullptr;
3031 CurrentType = nullptr;
3032 switch (Kind) {
3033 // Types.
3034 case SymbolKind::S_UDT:
3035 CurrentType = Reader->createTypeDefinition();
3036 CurrentType->setTag(dwarf::DW_TAG_typedef);
3037 return CurrentType;
3038
3039 // Symbols.
3040 case SymbolKind::S_CONSTANT:
3041 CurrentSymbol = Reader->createSymbol();
3042 CurrentSymbol->setIsConstant();
3043 CurrentSymbol->setTag(dwarf::DW_TAG_constant);
3044 return CurrentSymbol;
3045
3046 case SymbolKind::S_BPREL32:
3047 case SymbolKind::S_REGREL32:
3048 case SymbolKind::S_GDATA32:
3049 case SymbolKind::S_LDATA32:
3050 case SymbolKind::S_LOCAL:
3051 // During the symbol traversal more information is available to
3052 // determine if the symbol is a parameter or a variable. At this
3053 // stage mark it as variable.
3054 CurrentSymbol = Reader->createSymbol();
3055 CurrentSymbol->setIsVariable();
3056 CurrentSymbol->setTag(dwarf::DW_TAG_variable);
3057 return CurrentSymbol;
3058
3059 // Scopes.
3060 case SymbolKind::S_BLOCK32:
3061 CurrentScope = Reader->createScope();
3062 CurrentScope->setIsLexicalBlock();
3063 CurrentScope->setTag(dwarf::DW_TAG_lexical_block);
3064 return CurrentScope;
3065 case SymbolKind::S_COMPILE2:
3066 case SymbolKind::S_COMPILE3:
3067 CurrentScope = Reader->createScopeCompileUnit();
3068 CurrentScope->setTag(dwarf::DW_TAG_compile_unit);
3069 Reader->setCompileUnit(static_cast<LVScopeCompileUnit *>(CurrentScope));
3070 return CurrentScope;
3071 case SymbolKind::S_INLINESITE:
3072 case SymbolKind::S_INLINESITE2:
3073 CurrentScope = Reader->createScopeFunctionInlined();
3074 CurrentScope->setIsInlinedFunction();
3075 CurrentScope->setTag(dwarf::DW_TAG_inlined_subroutine);
3076 return CurrentScope;
3077 case SymbolKind::S_LPROC32:
3078 case SymbolKind::S_GPROC32:
3079 case SymbolKind::S_LPROC32_ID:
3080 case SymbolKind::S_GPROC32_ID:
3081 case SymbolKind::S_SEPCODE:
3082 case SymbolKind::S_THUNK32:
3083 CurrentScope = Reader->createScopeFunction();
3084 CurrentScope->setIsSubprogram();
3085 CurrentScope->setTag(dwarf::DW_TAG_subprogram);
3086 return CurrentScope;
3087 default:
3088 // If '--internal=tag' and '--print=warning' are specified in the command
3089 // line, we record and print each seen 'SymbolKind'.
3090 break;
3091 }
3092 return nullptr;
3093}
3094
3096 LVElement *Element = Shared->TypeRecords.find(StreamTPI, TI);
3097 if (!Element) {
3098 // We are dealing with a base type or pointer to a base type, which are
3099 // not included explicitly in the CodeView format.
3101 Element = createElement(Kind);
3102 Element->setIsFinalized();
3103 Shared->TypeRecords.add(StreamTPI, (TypeIndex)Kind, Kind, Element);
3104 Element->setOffset(Kind);
3105 return Element;
3106 }
3107 // We are dealing with a pointer to a base type.
3109 Element = createElement(Kind);
3110 Shared->TypeRecords.add(StreamTPI, TI, Kind, Element);
3111 Element->setOffset(TI.getIndex());
3112 Element->setOffsetFromTypeIndex();
3113 return Element;
3114 }
3115
3116 W.printString("** Not implemented. **");
3117 printTypeIndex("TypeIndex", TI, StreamTPI);
3118 W.printString("TypeLeafKind", formatTypeLeafKind(Kind));
3119 return nullptr;
3120 }
3121
3122 Element->setOffset(TI.getIndex());
3123 Element->setOffsetFromTypeIndex();
3124 return Element;
3125}
3126
3127void LVLogicalVisitor::createDataMember(CVMemberRecord &Record, LVScope *Parent,
3129 MemberAccess Access) {
3130 LLVM_DEBUG({
3131 printTypeIndex("TypeIndex", TI, StreamTPI);
3132 W.printString("TypeName", Name);
3133 });
3134
3135 createElement(Record.Kind);
3136 if (LVSymbol *Symbol = CurrentSymbol) {
3137 Symbol->setName(Name);
3138 if (TI.isNoneType() || TI.isSimple())
3139 Symbol->setType(getElement(StreamTPI, TI));
3140 else {
3142 CVType CVMemberType = Types.getType(TI);
3143 if (CVMemberType.kind() == LF_BITFIELD) {
3144 if (Error Err = finishVisitation(CVMemberType, TI, Symbol)) {
3145 consumeError(std::move(Err));
3146 return;
3147 }
3148 } else
3149 Symbol->setType(getElement(StreamTPI, TI));
3150 }
3151 Symbol->setAccessibilityCode(Access);
3152 Parent->addElement(Symbol);
3153 }
3154}
3155
3156LVSymbol *LVLogicalVisitor::createParameter(LVElement *Element, StringRef Name,
3157 LVScope *Parent) {
3158 LVSymbol *Parameter = Reader->createSymbol();
3159 Parent->addElement(Parameter);
3160 Parameter->setIsParameter();
3161 Parameter->setTag(dwarf::DW_TAG_formal_parameter);
3162 Parameter->setName(Name);
3163 Parameter->setType(Element);
3164 return Parameter;
3165}
3166
3167LVSymbol *LVLogicalVisitor::createParameter(TypeIndex TI, StringRef Name,
3168 LVScope *Parent) {
3169 return createParameter(getElement(StreamTPI, TI), Name, Parent);
3170}
3171
3172LVType *LVLogicalVisitor::createBaseType(TypeIndex TI, StringRef TypeName) {
3173 TypeLeafKind SimpleKind = (TypeLeafKind)TI.getSimpleKind();
3174 TypeIndex TIR = (TypeIndex)SimpleKind;
3175 LLVM_DEBUG({
3176 printTypeIndex("TypeIndex", TIR, StreamTPI);
3177 W.printString("TypeName", TypeName);
3178 });
3179
3180 if (LVElement *Element = Shared->TypeRecords.find(StreamTPI, TIR))
3181 return static_cast<LVType *>(Element);
3182
3183 if (createElement(TIR, SimpleKind)) {
3184 CurrentType->setName(TypeName);
3186 }
3187 return CurrentType;
3188}
3189
3190LVType *LVLogicalVisitor::createPointerType(TypeIndex TI, StringRef TypeName) {
3191 LLVM_DEBUG({
3192 printTypeIndex("TypeIndex", TI, StreamTPI);
3193 W.printString("TypeName", TypeName);
3194 });
3195
3196 if (LVElement *Element = Shared->TypeRecords.find(StreamTPI, TI))
3197 return static_cast<LVType *>(Element);
3198
3199 LVType *Pointee = createBaseType(TI, TypeName.drop_back(1));
3200 if (createElement(TI, TypeLeafKind::LF_POINTER)) {
3201 CurrentType->setIsFinalized();
3202 CurrentType->setType(Pointee);
3204 }
3205 return CurrentType;
3206}
3207
3208void LVLogicalVisitor::createParents(StringRef ScopedName, LVElement *Element) {
3209 // For the given test case:
3210 //
3211 // struct S { enum E { ... }; };
3212 // S::E V;
3213 //
3214 // 0 | S_LOCAL `V`
3215 // type=0x1004 (S::E), flags = none
3216 // 0x1004 | LF_ENUM `S::E`
3217 // options: has unique name | is nested
3218 // 0x1009 | LF_STRUCTURE `S`
3219 // options: contains nested class
3220 //
3221 // When the local 'V' is processed, its type 'E' is created. But There is
3222 // no direct reference to its parent 'S'. We use the scoped name for 'E',
3223 // to create its parents.
3224
3225 // The input scoped name must have at least parent and nested names.
3226 // Drop the last element name, as it corresponds to the nested type.
3227 LVStringRefs Components = getAllLexicalComponents(ScopedName);
3228 if (Components.size() < 2)
3229 return;
3230 Components.pop_back();
3231
3232 LVStringRefs::size_type FirstNamespace;
3233 LVStringRefs::size_type FirstAggregate;
3234 std::tie(FirstNamespace, FirstAggregate) =
3235 Shared->NamespaceDeduction.find(Components);
3236
3237 LLVM_DEBUG({
3238 W.printString("First Namespace", Components[FirstNamespace]);
3239 W.printString("First NonNamespace", Components[FirstAggregate]);
3240 });
3241
3242 // Create any referenced namespaces.
3243 if (FirstNamespace < FirstAggregate) {
3244 Shared->NamespaceDeduction.get(
3245 LVStringRefs(Components.begin() + FirstNamespace,
3246 Components.begin() + FirstAggregate));
3247 }
3248
3249 // Traverse the enclosing scopes (aggregates) and create them. In the
3250 // case of nested empty aggregates, MSVC does not emit a full record
3251 // description. It emits only the reference record.
3252 LVScope *Aggregate = nullptr;
3253 TypeIndex TIAggregate;
3254 std::string AggregateName = getScopedName(
3255 LVStringRefs(Components.begin(), Components.begin() + FirstAggregate));
3256
3257 // This traversal is executed at least once.
3258 for (LVStringRefs::size_type Index = FirstAggregate;
3259 Index < Components.size(); ++Index) {
3260 AggregateName = getScopedName(LVStringRefs(Components.begin() + Index,
3261 Components.begin() + Index + 1),
3262 AggregateName);
3263 TIAggregate = Shared->ForwardReferences.remap(
3264 Shared->TypeRecords.find(StreamTPI, AggregateName));
3265 Aggregate =
3266 TIAggregate.isNoneType()
3267 ? nullptr
3268 : static_cast<LVScope *>(getElement(StreamTPI, TIAggregate));
3269 }
3270
3271 // Workaround for cases where LF_NESTTYPE is missing for nested templates.
3272 // If we manage to get parent information from the scoped name, we can add
3273 // the nested type without relying on the LF_NESTTYPE.
3274 if (Aggregate && !Element->getIsScopedAlready()) {
3275 Aggregate->addElement(Element);
3276 Element->setIsScopedAlready();
3277 }
3278}
3279
3281 LVScope *Parent) {
3282 LLVM_DEBUG({ printTypeIndex("TypeIndex", TI, StreamTPI); });
3283 TI = Shared->ForwardReferences.remap(TI);
3284 LLVM_DEBUG({ printTypeIndex("TypeIndex Remap", TI, StreamTPI); });
3285
3286 LVElement *Element = Shared->TypeRecords.find(StreamIdx, TI);
3287 if (!Element) {
3288 if (TI.isNoneType() || TI.isSimple()) {
3289 StringRef TypeName = TypeIndex::simpleTypeName(TI);
3290 // If the name ends with "*", create 2 logical types: a pointer and a
3291 // pointee type. TypeIndex is composed of a SympleTypeMode byte followed
3292 // by a SimpleTypeKind byte. The logical pointer will be identified by
3293 // the full TypeIndex value and the pointee by the SimpleTypeKind.
3294 return (TypeName.back() == '*') ? createPointerType(TI, TypeName)
3295 : createBaseType(TI, TypeName);
3296 }
3297
3298 LLVM_DEBUG({ W.printHex("TypeIndex not implemented: ", TI.getIndex()); });
3299 return nullptr;
3300 }
3301
3302 // The element has been finalized.
3303 if (Element->getIsFinalized())
3304 return Element;
3305
3306 // Add the element in case of a given parent.
3307 if (Parent)
3308 Parent->addElement(Element);
3309
3310 // Check for a composite type.
3312 CVType CVRecord = Types.getType(TI);
3313 if (Error Err = finishVisitation(CVRecord, TI, Element)) {
3314 consumeError(std::move(Err));
3315 return nullptr;
3316 }
3317 Element->setIsFinalized();
3318 return Element;
3319}
3320
3322 // Traverse the collected LF_UDT_SRC_LINE records and add the source line
3323 // information to the logical elements.
3324 for (const TypeIndex &Entry : Shared->LineRecords) {
3325 CVType CVRecord = ids().getType(Entry);
3328 const_cast<CVType &>(CVRecord), Line))
3329 consumeError(std::move(Err));
3330 else {
3331 LLVM_DEBUG({
3332 printTypeIndex("UDT", Line.getUDT(), StreamIPI);
3333 printTypeIndex("SourceFile", Line.getSourceFile(), StreamIPI);
3334 W.printNumber("LineNumber", Line.getLineNumber());
3335 });
3336
3337 // The TypeIndex returned by 'getUDT()' must point to an already
3338 // created logical element. If no logical element is found, it means
3339 // the LF_UDT_SRC_LINE is associated with a system TypeIndex.
3340 if (LVElement *Element = Shared->TypeRecords.find(
3341 StreamTPI, Line.getUDT(), /*Create=*/false)) {
3342 Element->setLineNumber(Line.getLineNumber());
3343 Element->setFilenameIndex(
3344 Shared->StringRecords.findIndex(Line.getSourceFile()));
3345 }
3346 }
3347 }
3348}
3349
3351 // Create namespaces.
3352 Shared->NamespaceDeduction.init();
3353}
3354
3355void LVLogicalVisitor::processFiles() { Shared->StringRecords.addFilenames(); }
3356
3358 if (!options().getInternalTag())
3359 return;
3360
3361 unsigned Count = 0;
3362 auto PrintItem = [&](StringRef Name) {
3363 auto NewLine = [&]() {
3364 if (++Count == 4) {
3365 Count = 0;
3366 OS << "\n";
3367 }
3368 };
3369 OS << format("%20s", Name.str().c_str());
3370 NewLine();
3371 };
3372
3373 OS << "\nTypes:\n";
3374 for (const TypeLeafKind &Kind : Shared->TypeKinds)
3375 PrintItem(formatTypeLeafKind(Kind));
3376 Shared->TypeKinds.clear();
3377
3378 Count = 0;
3379 OS << "\nSymbols:\n";
3380 for (const SymbolKind &Kind : Shared->SymbolKinds)
3382 Shared->SymbolKinds.clear();
3383
3384 OS << "\n";
3385}
3386
3388 LVScope *InlinedFunction,
3390 // Get the parent scope to update the address ranges of the nested
3391 // scope representing the inlined function.
3392 LVAddress ParentLowPC = 0;
3393 LVScope *Parent = InlinedFunction->getParentScope();
3394 if (const LVLocations *Locations = Parent->getRanges()) {
3395 if (!Locations->empty())
3396 ParentLowPC = (*Locations->begin())->getLowerAddress();
3397 }
3398
3399 // For the given inlinesite, get the initial line number and its
3400 // source filename. Update the logical scope representing it.
3401 uint32_t LineNumber = 0;
3403 LVInlineeInfo::iterator Iter = InlineeInfo.find(InlineSite.Inlinee);
3404 if (Iter != InlineeInfo.end()) {
3405 LineNumber = Iter->second.first;
3406 Filename = Iter->second.second;
3407 AbstractFunction->setLineNumber(LineNumber);
3408 // TODO: This part needs additional work in order to set properly the
3409 // correct filename in order to detect changes between filenames.
3410 // AbstractFunction->setFilename(Filename);
3411 }
3412
3413 LLVM_DEBUG({
3414 dbgs() << "inlineSiteAnnotation\n"
3415 << "Abstract: " << AbstractFunction->getName() << "\n"
3416 << "Inlined: " << InlinedFunction->getName() << "\n"
3417 << "Parent: " << Parent->getName() << "\n"
3418 << "Low PC: " << hexValue(ParentLowPC) << "\n";
3419 });
3420
3421 // Get the source lines if requested by command line option.
3422 if (!options().getPrintLines())
3423 return Error::success();
3424
3425 // Limitation: Currently we don't track changes in the FileOffset. The
3426 // side effects are the caller that it is unable to differentiate the
3427 // source filename for the inlined code.
3428 uint64_t CodeOffset = ParentLowPC;
3429 int32_t LineOffset = LineNumber;
3430 uint32_t FileOffset = 0;
3431
3432 auto UpdateClose = [&]() { LLVM_DEBUG({ dbgs() << ("\n"); }); };
3433 auto UpdateCodeOffset = [&](uint32_t Delta) {
3434 CodeOffset += Delta;
3435 LLVM_DEBUG({
3436 dbgs() << formatv(" code 0x{0} (+0x{1})", utohexstr(CodeOffset),
3437 utohexstr(Delta));
3438 });
3439 };
3440 auto UpdateLineOffset = [&](int32_t Delta) {
3441 LineOffset += Delta;
3442 LLVM_DEBUG({
3443 char Sign = Delta > 0 ? '+' : '-';
3444 dbgs() << formatv(" line {0} ({1}{2})", LineOffset, Sign,
3445 std::abs(Delta));
3446 });
3447 };
3448 auto UpdateFileOffset = [&](int32_t Offset) {
3449 FileOffset = Offset;
3450 LLVM_DEBUG({ dbgs() << formatv(" file {0}", FileOffset); });
3451 };
3452
3454 auto CreateLine = [&]() {
3455 // Create the logical line record.
3456 LVLineDebug *Line = Reader->createLineDebug();
3457 Line->setAddress(CodeOffset);
3458 Line->setLineNumber(LineOffset);
3459 // TODO: This part needs additional work in order to set properly the
3460 // correct filename in order to detect changes between filenames.
3461 // Line->setFilename(Filename);
3462 InlineeLines.push_back(Line);
3463 };
3464
3465 bool SeenLowAddress = false;
3466 bool SeenHighAddress = false;
3467 uint64_t LowPC = 0;
3468 uint64_t HighPC = 0;
3469
3470 for (auto &Annot : InlineSite.annotations()) {
3471 LLVM_DEBUG({
3472 dbgs() << formatv(" {0}",
3473 fmt_align(toHex(Annot.Bytes), AlignStyle::Left, 9));
3474 });
3475
3476 // Use the opcode to interpret the integer values.
3477 switch (Annot.OpCode) {
3478 case BinaryAnnotationsOpCode::ChangeCodeOffset:
3479 case BinaryAnnotationsOpCode::CodeOffset:
3480 case BinaryAnnotationsOpCode::ChangeCodeLength:
3481 UpdateCodeOffset(Annot.U1);
3482 UpdateClose();
3483 if (Annot.OpCode == BinaryAnnotationsOpCode::ChangeCodeOffset) {
3484 CreateLine();
3485 LowPC = CodeOffset;
3486 SeenLowAddress = true;
3487 break;
3488 }
3489 if (Annot.OpCode == BinaryAnnotationsOpCode::ChangeCodeLength) {
3490 HighPC = CodeOffset - 1;
3491 SeenHighAddress = true;
3492 }
3493 break;
3494 case BinaryAnnotationsOpCode::ChangeCodeLengthAndCodeOffset:
3495 UpdateCodeOffset(Annot.U2);
3496 UpdateClose();
3497 break;
3498 case BinaryAnnotationsOpCode::ChangeLineOffset:
3499 case BinaryAnnotationsOpCode::ChangeCodeOffsetAndLineOffset:
3500 UpdateCodeOffset(Annot.U1);
3501 UpdateLineOffset(Annot.S1);
3502 UpdateClose();
3503 if (Annot.OpCode ==
3504 BinaryAnnotationsOpCode::ChangeCodeOffsetAndLineOffset)
3505 CreateLine();
3506 break;
3507 case BinaryAnnotationsOpCode::ChangeFile:
3508 UpdateFileOffset(Annot.U1);
3509 UpdateClose();
3510 break;
3511 default:
3512 break;
3513 }
3514 if (SeenLowAddress && SeenHighAddress) {
3515 SeenLowAddress = false;
3516 SeenHighAddress = false;
3517 InlinedFunction->addObject(LowPC, HighPC);
3518 }
3519 }
3520
3521 Reader->addInlineeLines(InlinedFunction, InlineeLines);
3522 UpdateClose();
3523
3524 return Error::success();
3525}
amdgpu Simplify well known AMD library false FunctionCallee Value * Arg
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
@ Flags
Definition: TextStubV5.cpp:93
@ Names
Definition: TextStubV5.cpp:106
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:163
An implementation of BinaryStream which holds its entire data set in a single contiguous buffer.
Provides read only access to a subclass of BinaryStream.
Stores all information relating to a compile unit, be it in its original instance in the object file ...
This is an important base class in LLVM.
Definition: Constant.h:41
Lightweight error class with error context and mandatory checking.
Definition: Error.h:156
static ErrorSuccess success()
Create a success value.
Definition: Error.h:330
Tagged union holding either a T or a Error.
Definition: Error.h:470
StringRef getName() const
Definition: Record.h:1618
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)
void printFlags(StringRef Label, T Value, ArrayRef< EnumEntry< TFlag > > Flags, TFlag EnumMask1={}, TFlag EnumMask2={}, TFlag EnumMask3={})
virtual raw_ostream & getOStream()
virtual raw_ostream & startLine()
virtual void printNumber(StringRef Label, char Value)
void printHex(StringRef Label, T Value)
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:1200
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:378
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:720
uint32_t getFlags() const
Definition: SymbolRecord.h:721
CompileSym3Flags getFlags() const
Definition: SymbolRecord.h:754
SourceLanguage getLanguage() const
Definition: SymbolRecord.h:751
Represents a read-only view of a CodeView string table.
DefRangeFramePointerRelHeader Hdr
Definition: SymbolRecord.h:543
std::vector< LocalVariableAddrGap > Gaps
Definition: SymbolRecord.h:545
DefRangeRegisterRelHeader Hdr
Definition: SymbolRecord.h:578
std::vector< LocalVariableAddrGap > Gaps
Definition: SymbolRecord.h:580
std::vector< LocalVariableAddrGap > Gaps
Definition: SymbolRecord.h:495
LocalVariableAddrRange Range
Definition: SymbolRecord.h:494
std::vector< LocalVariableAddrGap > Gaps
Definition: SymbolRecord.h:519
DefRangeSubfieldRegisterHeader Hdr
Definition: SymbolRecord.h:517
std::vector< LocalVariableAddrGap > Gaps
Definition: SymbolRecord.h:473
LocalVariableAddrRange Range
Definition: SymbolRecord.h:472
std::vector< LocalVariableAddrGap > Gaps
Definition: SymbolRecord.h:451
uint32_t getRelocationOffset() const
Definition: SymbolRecord.h:445
LocalVariableAddrRange Range
Definition: SymbolRecord.h:450
RegisterId getLocalFramePtrReg(CPUType CPU) const
Extract the register this frame uses to refer to local variables.
Definition: SymbolRecord.h:783
RegisterId getParamFramePtrReg(CPUType CPU) const
Extract the register this frame uses to refer to parameters.
Definition: SymbolRecord.h:789
FrameProcedureOptions Flags
Definition: SymbolRecord.h:780
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
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:268
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:255
void setOffset(LVOffset DieOffset)
Definition: LVObject.h:240
LVOffset getOffset() const
Definition: LVObject.h:239
void setLineNumber(uint32_t Number)
Definition: LVObject.h:277
void setTag(dwarf::Tag Tag)
Definition: LVObject.h:232
codeview::CPUType getCompileUnitCPUType()
Definition: LVReader.h:256
void setCompileUnitCPUType(codeview::CPUType Type)
Definition: LVReader.h:253
virtual bool isSystemEntry(LVElement *Element, StringRef Name={}) const
Definition: LVReader.h:276
LVScopeCompileUnit * getCompileUnit() const
Definition: LVReader.h:248
void setCompileUnit(LVScope *Scope)
Definition: LVReader.h:249
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:355
MethodKind
Part of member attribute flags. (CV_methodprop_e)
Definition: CodeView.h:272
CPUType
These values correspond to the CV_CPU_TYPE_e enumeration, and are documented here: https://msdn....
Definition: CodeView.h:75
bool symbolEndsScope(SymbolKind Kind)
Return true if this ssymbol ends a scope.
MethodOptions
Equivalent to CV_fldattr_t bitfield.
Definition: CodeView.h:283
ArrayRef< EnumEntry< SymbolKind > > getSymbolTypeNames()
Definition: EnumTables.cpp:440
MemberAccess
Source-level access specifier. (CV_access_e)
Definition: CodeView.h:264
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:33
ArrayRef< EnumEntry< uint16_t > > getLocalFlagNames()
Definition: EnumTables.cpp:465
ArrayRef< EnumEntry< uint16_t > > getRegisterNames(CPUType Cpu)
Definition: EnumTables.cpp:448
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:461
TypeRecordKind
Distinguishes individual records in .debug$T or .debug$P section or PDB type stream.
Definition: CodeView.h:26
SymbolKind
Duplicate copy of the above enum, but using the official CV names.
Definition: CodeView.h:47
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:489
ArrayRef< EnumEntry< SourceLanguage > > getSourceLanguageNames()
Definition: EnumTables.cpp:473
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:481
void printTypeIndex(ScopedPrinter &Printer, StringRef FieldName, TypeIndex TI, TypeCollection &Types)
Definition: TypeIndex.cpp:93
@ DW_INL_inlined
Definition: Dwarf.h:424
@ DW_INL_declared_inlined
Definition: Dwarf.h:426
Attribute
Attributes.
Definition: Dwarf.h:123
constexpr Tag DW_TAG_unaligned
Definition: LVObject.h:29
FormattedNumber hexValue(uint64_t N, unsigned Width=HEX_WIDTH, bool Upper=false)
Definition: LVSupport.h:104
LVReader & getReader()
Definition: LVReader.h:334
static TypeIndex getTrueType(TypeIndex &TI)
std::vector< StringRef > LVStringRefs
Definition: LVSupport.h:34
uint8_t LVSmall
Definition: LVObject.h:43
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:37
std::string formatTypeLeafKind(codeview::TypeLeafKind K)
Definition: FormatUtil.cpp:115
Print(const T &, const DataFlowGraph &) -> Print< T >
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
auto formatv(const char *Fmt, Ts &&... Vals) -> formatv_object< decltype(std::make_tuple(detail::build_format_adapter(std::forward< Ts >(Vals))...))>
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:1839
std::string demangle(const std::string &MangledName)
Attempt to demangle a string using different demangling schemes.
Definition: Demangle.cpp:29
std::tuple< uint64_t, uint32_t > InlineSite
Definition: MCPseudoProbe.h:99
detail::AlignAdapter< T > fmt_align(T &&Item, AlignStyle Where, size_t Amount, char Fill=' ')
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:124
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.
detail::RepeatAdapter< T > fmt_repeat(T &&Item, size_t Count)
void consumeError(Error Err)
Consume a Error without doing anything.
Definition: Error.h:1043
#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